如何从字符串数组生成TypeScript对象类型定义
解决TypeScript字符串数组转对象的类型推断问题
要让函数返回的对象类型和输入的字符串数组元素精确匹配,关键是用泛型捕获具体的字符串字面量类型,而不是用宽泛的string[]。
修改后的代码方案
const func = <T extends readonly string[]>(keys: T): { [K in T[number]]: true } => { return keys.reduce((acc, key) => { return { ...acc, [key]: true, }; }, {} as { [K in T[number]]: true }); }; // 测试示例 const result = func(["foo"]); // 类型为 { "foo": true } const result2 = func(["foo", "bar"]); // 类型为 { "foo": true; "bar": true }
关键解释
- 泛型约束:
<T extends readonly string[]>让TypeScript记住传入数组的具体字符串字面量类型(比如["foo"]而不是模糊的string[])。 - 映射类型:
{ [K in T[number]]: true }生成一个对象类型,其中键是数组中所有字符串元素,值固定为true(比boolean更精确,因为你的逻辑里值永远是true)。 - 类型断言:
{} as { [K in T[number]]: true }告诉TypeScript,reduce的初始空对象最终会被填充为目标类型,避免累加器类型被推断为{}。
简化版(用Record类型)
如果觉得映射类型写起来麻烦,也可以用TypeScript内置的Record类型:
const func = <T extends readonly string[]>(keys: T): Record<T[number], true> => { return keys.reduce((acc, key) => ({ ...acc, [key]: true }), {} as Record<T[number], true>); };
两者效果一致,选择你觉得更易读的写法即可。
内容的提问来源于stack exchange,提问作者Will Wise
相关产品推荐
相关产品推荐

