如何基于类型化对象数组的指定键推断对应字面量元组类型?
问题原因
TypeScript 标准库中Array.prototype.map的类型定义针对通用数组场景设计,没有针对固定长度的只读元组做针对性的类型重载,所以哪怕你给原数组加了as const断言被推导为固定长度元组,调用map后默认也只会返回元素联合类型组成的普通数组,不会保留原数组的长度信息。
解决方案
最通用的方式是自定义一个适配元组场景的mapTuple工具函数,通过泛型约束保留输入元组的长度,映射输出对应长度的元组类型:
// 工具函数定义,如果需要可变元组,可去掉返回类型里的readonly修饰符 function mapTuple<T extends readonly any[], MapperResult>( inputTuple: T, mapper: (item: T[number], index: number, originalTuple: T) => MapperResult ): { readonly [K in keyof T]: MapperResult } { return inputTuple.map(mapper) as any; } // 业务代码示例 const list = [ { _id: 'foo1' }, { _id: 'foo2' } ] as const const listIds = mapTuple(list, listValue => listValue._id) // 此时listIds的类型为 readonly ["foo1", "foo2"],符合预期
如果不想额外引入工具函数,也可以在调用map后手动断言类型,不过这种方式没有动态类型校验,修改原数组时需要同步修改断言类型,不推荐用于动态变化的数组:
const listIds = list.map(listValue => listValue._id) as ['foo1', 'foo2']
内容的提问来源于stack exchange,提问作者Adam Gerthel
相关产品推荐
相关产品推荐

