如何为动态生成键的TypeScript函数定义精确返回类型?
问题
我有一个接收字符串数组作为参数的函数,它会构建一个以数组元素为键的对象,示例代码如下:
function buildObject(keys: string[]) { let obj = {}; for (let i = 0; i < keys.length; i++) { obj[keys[i]] = i; } return obj; }
请问是否可以为该函数定义返回类型,使得访问未定义的对象键时会触发编译器错误?示例如下:
const obj = buildObject(['a', 'b', 'b']); console.log(obj.a) // 正常 console.log(obj.d) // 希望此处触发编译器错误
解答
可以实现,核心是借助TypeScript的泛型和字面量类型推断,让编译器捕获传入数组的具体键名,同时处理重复键的覆盖情况。
具体实现
通过泛型约束数组元素为字符串字面量,再用映射类型定义返回对象的结构:
function buildObject<T extends string>(keys: readonly T[]): { [K in T]: number } { const obj = {} as { [K in T]: number }; for (let i = 0; i < keys.length; i++) { obj[keys[i]] = i; } return obj; }
效果验证
调用const obj = buildObject(['a', 'b', 'b'])时,TypeScript会自动推断返回类型为{ a: number; b: number }:
- 访问
obj.a或obj.b时完全正常,无编译错误。 - 访问
obj.d时,编译器会立即报错:属性'd'不存在于类型'{ a: number; b: number }'上,完全符合预期。
注意事项
如果传入的是动态生成的字符串数组(而非字面量数组),TypeScript无法在编译期确定具体键名,此时返回类型会退化为{ [key: string]: number },这种情况下访问任意字符串键都不会触发错误,这是TypeScript类型系统的固有限制。
内容的提问来源于stack exchange,提问作者Sergey Shevchenko
相关产品推荐
相关产品推荐

