使用TypeScript泛型重构只读数组类型的问题
问题描述
尝试重构只读数组类型时遇到问题:当前getValues函数返回的是包含联合类型元素的数组,期望返回对应每个输入key的具体元组组成的只读数组。
代码示例
const store: Record<string, any> = { aaa: '123', bbb: null, ccc: [] } const getValues = <Keys extends readonly string[]>(keys: Keys): ReadonlyArray<[Keys[number], unknown]> => { return keys.map((key) => ([key, key in store ? store[key] : null])) } const keyArr = ['aaa', 'bbb'] as const getValues(keyArr) // 当前函数返回类型: readonly ["aaa" | "bbb", unknown][] // 期望的返回类型: readonly [["aaa", unknown], ["bbb", unknown]]
解决方案
要让TypeScript推断出对应输入元组的具体返回元组,需要使用映射类型遍历输入元组的每个元素,而非直接使用Keys[number]合并成联合类型。修改后的代码如下:
const store: Record<string, any> = { aaa: '123', bbb: null, ccc: [] } // 用映射类型逐个转换输入元组的元素为对应[key, value]元组 const getValues = <Keys extends readonly string[]>(keys: Keys): { readonly [K in keyof Keys]: [Keys[K], unknown] } => { // Array.map默认返回数组,需断言为目标元组类型 return keys.map((key) => ([key, key in store ? store[key] : null])) as any } const keyArr = ['aaa', 'bbb'] as const const result = getValues(keyArr) // 现在result的类型是: readonly [["aaa", unknown], ["bbb", unknown]]
关键说明
- 替换返回值类型为
{ readonly [K in keyof Keys]: [Keys[K], unknown] },TypeScript会逐个映射输入元组的每个索引,生成对应的具体元组项,避免合并成联合类型。 - 由于
Array.prototype.map的默认返回类型是数组(而非元组),需要通过类型断言告诉TypeScript实际返回的是目标元组类型,as any是简洁的实现方式,若追求严谨也可自定义元组映射函数。
内容的提问来源于stack exchange,提问作者lyswhut
相关产品推荐
相关产品推荐

