TypeScript如何根据对象键数组获取返回值的精确元组类型
实现精确元组类型返回的方案
要拿到和传入键顺序、值一一对应的精确元组返回类型,核心是通过映射元组类型逐位匹配键和对应值的类型,避免将元组类型放宽为普通数组、联合类型。
正确实现代码
// 定义映射工具类型:遍历键元组的每个索引位置,取出对象对应键的属性类型 type MapKeysToValues<T, K extends readonly (keyof T)[]> = { [Index in keyof K]: K[Index] extends keyof T ? T[K[Index]] : never } function mapObjToArray<T extends object, K extends readonly (keyof T)[]>( obj: T, keys: [...K] // 可变元组语法,提示TS将入参推导为元组而非普通数组 ): MapKeysToValues<T, K> { // 内部map的返回值TS无法自动推导匹配元组,加类型断言即可,逻辑上类型安全 return keys.map(key => obj[key]) as MapKeysToValues<T, K> }
效果验证
const obj = { A: "a", B: "b", C: 'c', X: 'x'} as const const result = mapObjToArray(obj, ['A', 'B']) // result 类型被精确推导为 readonly ["a", "b"],完全符合预期
原有写法的问题
- 基础泛型写法:
keys标注为(keyof T)[]时,TS会将传入的键数组推导为普通数组类型,丢失每个位置的字面量键信息,最终只能返回所有属性值组成的联合类型数组。 - 可变元组优化写法:返回值使用
T[X[number]][]时,X[number]会将元组所有位置的键合并为联合类型,丢失元组的顺序、位置信息,最终只能得到属性值联合的数组,无法得到定长精确元组。
使用提示
- 传入普通对象时,返回元组对应位置的类型为对象属性的原始类型;传入加了
as const的常量对象时,返回元组对应位置会推导出精确的字面量类型。 - 不需要额外给传入的键数组加
as const,keys: [...K]的写法会自动引导TS将数组字面量推导为元组类型。
内容的提问来源于stack exchange,提问作者sho otani
相关产品推荐
相关产品推荐

