TypeScript中如何在联合类型使用字符串常量作为计算标识符?
TypeScript联合类型中使用对象属性作为计算属性标识符的问题
问题场景
我定义了如下联合类型:
interface Cell {}; type CellInfo = | { Provisioned: Cell } | { Cloned: Cell };
尝试用单个常量替代字符串字面量是可行的:
interface Cell {}; const PROVISIONED = "Provisioned"; type CellInfo = | { [PROVISIONED]: Cell } | { Cloned: Cell };
但改用对象存储常量时写法失效:
interface Cell {}; const CELL_TYPE = { PROVISIONED: "Provisioned", CLONED: "CLONED", }; type CellInfo = | { [CELL_TYPE.PROVISIONED]: Cell } | { [CELL_TYPE.CLONED]: Cell };
报错信息:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.(1170)
原因分析
单个const PROVISIONED = "Provisioned"会被TypeScript推断为字面量类型"Provisioned",符合计算属性对类型的要求;但普通对象CELL_TYPE的属性默认会被推断为宽泛的string类型,不是字面量类型,所以无法作为类型中的计算属性名。
解决方法
方案1:用as const断言锁定对象属性的字面量类型
给对象添加as const,让TypeScript保留每个属性的具体字面量值:
interface Cell {}; const CELL_TYPE = { PROVISIONED: "Provisioned", CLONED: "CLONED", } as const; // 关键:const断言 type CellInfo = | { [CELL_TYPE.PROVISIONED]: Cell } | { [CELL_TYPE.CLONED]: Cell };
方案2:使用字符串枚举(类型层面直接引用枚举成员)
字符串枚举的成员本身就是字面量类型,可以直接用于计算属性名:
interface Cell {}; enum CellType { Provisioned = "Provisioned", Cloned = "CLONED" } type CellInfo = | { [CellType.Provisioned]: Cell } | { [CellType.Cloned]: Cell };
内容的提问来源于stack exchange,提问作者Jost
相关产品推荐
相关产品推荐

