如何基于字符串枚举构建对象并简化其类型声明?
简化枚举对应对象的类型声明
问题场景
现有如下TypeScript代码,AppPaths的类型声明需逐个指定枚举值作为键,写法繁琐:
enum App { App1 = "my-app1", App2 = "my-app2", } const AppPaths: { [ App.App1 ]: string; [ App.App2 ]: string; } = { [ App.App1 ]: "/some/path/to/app1", [ App.App2 ]: "/some/path/to/app2", };
尝试简化时触发报错:
- 使用
{ [ key: keyof App ]: string }时,报错:索引签名参数类型不能是字面量类型或泛型类型。请考虑改用映射对象类型。
- 使用
{ [ key in keyof App ]: string }或{ [ key in keyof typeof App ]: string }时,报错:对象字面量只能指定已知属性,而“[ App.App1 ]”不在类型“{ readonly [x: number]: string; toString: string; charAt: string; charCodeAt: string; concat: string; indexOf: string; lastIndexOf: string; localeCompare: string; match: string; replace: string; search: string; ... 39 more ...; [Symbol.iterator]: string; }”中
原因解析
keyof App获取的是枚举的成员名称(即"App1"、"App2"),而非枚举的实际值("my-app1"、"my-app2"),和对象中使用的键(枚举值)不匹配。keyof typeof App指向枚举对象的类型,包含了String原型的所有方法(如toString、charAt等),与目标对象结构完全不符。
解决方案
需基于枚举的值类型定义AppPaths的类型,以下两种写法均可实现简化:
写法1:使用内置Record工具类型
Record<K, V>是TypeScript内置工具类型,用于快速定义“键类型为K、值类型为V”的对象,直接传入枚举App即可(其值类型为枚举值的联合类型):
enum App { App1 = "my-app1", App2 = "my-app2", } const AppPaths: Record<App, string> = { [App.App1]: "/some/path/to/app1", [App.App2]: "/some/path/to/app2", };
写法2:显式映射枚举值类型
若不想使用内置工具类型,可直接基于枚举值的联合类型编写映射类型:
enum App { App1 = "my-app1", App2 = "my-app2", } type AppPathsType = { [key in App]: string }; const AppPaths: AppPathsType = { [App.App1]: "/some/path/to/app1", [App.App2]: "/some/path/to/app2", };
两种写法均能匹配对象结构,同时大幅简化类型声明,不会触发报错。
内容的提问来源于stack exchange,提问作者Josh M.
相关产品推荐
相关产品推荐

