如何编写严格的泛型元组数组?实现元组泛型独立约束
解决方法
要让数组中每个元组使用独立的泛型约束,避免T被推断为联合类型,你可以通过可变元组泛型+映射类型实现严格绑定:
type MyTuple<T extends object> = [T, (s: NoInfer<T>) => any]; // 泛型T对应所有元组第一个元素组成的元组类型,映射类型确保每个位置的元组使用独立的T[K] const func = <T extends object[]>(arr: { [K in keyof T]: MyTuple<T[K]> }) => { // ... }; func([ [{ foo: 'bar' }, (s) => s.foo], // 正常通过 [{ foo2: 'bar' }, (s) => s.foo2], // 正常通过 [{ foo: 'bar' }, (s) => s.foo2], // 报错:类型“{ foo: string; }”上不存在属性“foo2” [{ foo: 'bar' }, (s) => s.foo3], // 报错:类型“{ foo: string; }”上不存在属性“foo3” ]);
原理说明
- 原代码中
Array<MyTuple<T>>会让TypeScript把所有元组的第一个元素合并为联合类型作为T,导致第二个参数可以访问联合类型的任意属性,无法触发错误。 - 修改后,泛型
T是一个元组类型,对应数组中每个元组第一个元素的类型集合。通过映射类型{ [K in keyof T]: MyTuple<T[K]> },强制每个数组元素使用对应位置的独立类型T[K],让第二个参数的类型严格绑定到当前元组的第一个元素,从而实现严格约束。
你也可以省略MyTuple类型,直接在映射类型中定义结构:
const func = <T extends object[]>(arr: { [K in keyof T]: [T[K], (s: NoInfer<T[K]>) => any] }) => { // ... };
内容的提问来源于stack exchange,提问作者Patrick L.
相关产品推荐
相关产品推荐

