TypeScript如何将字符串数组类型转为键为数组元素的对象类型
错误原因分析
第一种写法报错原因
keyof T作用于数组类型时,返回的是数组实例的自有属性键(包括数字索引0/1/2、数组方法名push/pop、属性length等),并非数组的元素值,所以最终生成的是数组类型,自然不存在foo这类属性。
as any写法的问题
as any会完全绕过TypeScript的类型检查,属于不符合规范的写法,同时会将生成对象的键类型放宽为任意字符串,因此访问不存在的键时不会触发错误提示。
正确实现
要实现需求,首先需要通过T[number]拿到数组类型的元素联合类型,再遍历该联合类型生成对象键即可:
// 泛型约束加入Readonly是为了兼容带const断言的运行时数组 type ObjectFromKeys<T extends ReadonlyArray<string>> = { [K in T[number]]: string }
效果验证
// 字面量类型测试 declare const o: ObjectFromKeys<['foo']> o.foo // 类型正常为string o.bar // 直接报错:Property 'bar' does not exist on type '{ foo: string; }' // 运行时数组配合const断言测试 const keys = ['foo', 'baz'] as const declare const o2: ObjectFromKeys<typeof keys> o2.baz // 正常 o2.bar // 报错
注意事项
如果上述代码中访问不存在的键仍未报错,请检查tsconfig.json中是否开启了strict: true,或者单独开启noImplicitAny: true即可。
内容的提问来源于stack exchange,提问作者David Alsh
相关产品推荐
相关产品推荐

