typescript 不透明的类型和索引签名

zkure5ic  于 2023-05-19  发布在  TypeScript
关注(0)|答案(1)|浏览(180)

创建不透明类型的常见方法似乎如下所示:

declare const sym: unique symbol;
type O = { [sym]: true };

(note这种类型是完全不透明的,没有品牌)。
这在某种意义上起作用,即没有其他任何东西可以分配给类型O。然而,假设我有一个索引签名类型(或记录):

type T = { [key: string]: number };

问题是类型O可以赋值给类型T:

const o: O = {} as O;
const t: T = o; // no error

我猜这是因为类型T包含空对象{},而O的示例可以赋值给它。理想情况下,我更希望O类型不能被赋值给任何东西,除了它自己(和任何)。有没有其他方法来声明opaque类型来实现这一点?

k5ifujac

k5ifujac1#

正如注解中所建议的,不允许将不透明类型O分配给索引签名类型的方法是将索引签名添加到不透明类型:

declare const sym: unique symbol;
type O = {
  [sym]: true;
  [key: PropertyKey]: unknown;
};

在这种情况下,如果我们的目标类型T有一个不能从类型O赋值给的索引签名,那么从O到T的赋值将是不允许的:

type T = { [key: string]: number; }
const o: O = {} as O;
const t: T = o; // Error: index signatures are incompatible

请注意,如果O中的签名类型可分配给T中的签名类型,则这将不起作用(不会触发错误),例如,如果

T = { [key: string]: unknown }

T = { [key: string]: any }

因此,这只是防止不透明类型可赋值性的部分解决方案。

相关问题