TypeScript中如何让DataPoint类型根据元素数量推断泛型参数?
解决方案
要实现让2元素数字数组推断为DataPoint<number>(第三个泛型为never),3元素数组推断为DataPoint<number, number>,可以通过调整泛型默认值+条件类型来实现:
1. 定义基础DataPoint类型
把第二个泛型参数的默认值设为never,并通过条件类型关联数组长度:
// 泛型U默认值为never,对应2元素数组;传入U时对应3元素数组 type DataPoint<T, U = never> = U extends never ? [T, T] : [T, T, U];
2. 实现自动推断的工具类型/函数
如果需要直接从数组字面量自动推断对应的DataPoint类型,可以用以下两种方式:
方式一:工具类型
// 从数组类型推断对应的DataPoint类型 type InferDataPoint<T extends any[]> = T extends [infer A, infer A] ? DataPoint<A> : T extends [infer A, infer A, infer B] ? DataPoint<A, B> : never; // 测试使用 const dp2: InferDataPoint<[1, 2]> = [1, 2]; // 类型显示为 DataPoint<number> const dp3: InferDataPoint<[1, 2, 3]> = [1, 2, 3]; // 类型显示为 DataPoint<number, number>
方式二:泛型函数(更便捷)
通过函数让TypeScript自动推断泛型参数,无需手动指定:
function createDataPoint<T extends number[]>(arr: T): InferDataPoint<T> { return arr as InferDataPoint<T>; } // 自动推断类型 const dp2 = createDataPoint([1, 2]); // 类型:DataPoint<number> const dp3 = createDataPoint([1, 2, 3]); // 类型:DataPoint<number, number>
3. 定义DataPoints类型
如果需要表示多个DataPoint的数组:
type DataPoints = (DataPoint<number> | DataPoint<number, number>)[]; // 示例 const points: DataPoints = [ [1, 2], // 类型为DataPoint<number> [3, 4, 5] // 类型为DataPoint<number, number> ];
关键原理
- 把第二个泛型参数的默认值从
number改为never,避免默认情况下自动填充为number。 - 利用条件类型
U extends never ? [T, T] : [T, T, U],让泛型参数和数组长度一一对应,从而实现类型显示的区分。
内容的提问来源于stack exchange,提问作者bemol
相关产品推荐
相关产品推荐

