如何定义与另一个元组长度相同的TypeScript泛型元组类型?
问题
我有一个函数,它接受一个由类型一致的元组组成的数据集:
type UnknownTuple = any[] function torgle<T extends UnknownTuple>(list: T[]) { ... }
我希望定义第二个参数,它的长度与这些元组相同,但类型不同(例如字符串标签):
const records = [ [7, 'Moo', true], [3, 'Sophie', false], [4, 'Tip', true] ] // 仅为示例;数据集在编译时未知 torgle(records, ['age', 'name', 'is_fuzzy']) // 合法 torgle(records, ['age', 'name']) // 报错
如何为第二个参数添加类型注解?
type UnknownTuple = any[] function torgle<T extends UnknownTuple>(list: T[], labels: ???) { ... }
注:有一个类似问题包含可变参数、高阶函数等额外内容,导致答案难以理解,因此用更简单的示例来澄清问题。
解决方案
你可以利用TypeScript的元组长度约束和元组类型映射实现需求,让第二个参数的类型是一个长度与输入元组完全一致的指定类型数组(比如字符串)。
修改后的函数类型注解如下:
type UnknownTuple = any[] function torgle<T extends UnknownTuple>( list: T[], labels: { [K in keyof T]: string } ) { ... }
原理说明
{ [K in keyof T]: string }是映射类型,它会遍历元组T的所有数字索引(比如0、1、2),并将每个位置的类型指定为string。- 元组的索引数量固定,这个映射类型最终会生成一个长度与
T完全相同的字符串元组类型,强制第二个参数的长度必须和输入元组一致。
验证效果
对于示例中的records数组,TypeScript会推断出T的类型是[number, string, boolean],因此labels的类型会被约束为[string, string, string]:
- 传入
['age', 'name', 'is_fuzzy']时类型匹配,编译通过; - 传入
['age', 'name']时长度不匹配,TypeScript直接抛出类型错误,符合预期。
如果需要labels元素支持其他类型,只需把string替换成你需要的类型(比如unknown或自定义类型)即可。
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

