TypeScript:如何强制函数所有输入的泛型参数LengthT一致?
问题描述
我用泛型定义了带长度感知的向量接口:
interface Vector<LengthT extends number> { length: LengthT, data: number[] }
可以创建类型系统能识别长度的向量实例:
const vector2a: Vector<2> = { length: 2, data: [1, 2] } const vector2b: Vector<2> = { length: 2, data: [3, 4] } const vector2c: Vector<2> = { length: 2, data: [5, 6] } const vector3: Vector<3> = { length: 3, data: [7, 8, 9] }
我想实现一个仅接受相同长度向量的addAll函数,但当前的定义限制不够严格:
// 当前写法无法拦截不同长度的向量传入 function addAll<LengthT extends number>(...vectors: Vector<LengthT>[]) { // 逐元素相加构造新Vector<LengthT>的逻辑 const resultLength = vectors[0]?.length || 0; const resultData = Array(resultLength).fill(0); for (const vec of vectors) { vec.data.forEach((val, idx) => { resultData[idx] += val; }); } return { length: resultLength as LengthT, data: resultData } as Vector<LengthT>; } // 此调用应被允许 const vector2Sum = addAll(vector2a, vector2b, vector2c) // 此调用应被禁止,但当前写法无法拦截 const vector2badSum = addAll(vector2a, vector3)
请问能否让addAll函数强制要求所有输入向量的LengthT值完全相同?
解决方案
完全可以实现,只需调整泛型的约束方式,通过元组类型锁定所有输入向量的长度类型一致性:
interface Vector<LengthT extends number> { length: LengthT, data: number[] } const vector2a: Vector<2> = { length: 2, data: [1, 2] } const vector2b: Vector<2> = { length: 2, data: [3, 4] } const vector2c: Vector<2> = { length: 2, data: [5, 6] } const vector3: Vector<3> = { length: 3, data: [7, 8, 9] } // 修改后的addAll函数 function addAll<LengthT extends number>(...vectors: [Vector<LengthT>, ...Vector<LengthT>[]]) { const resultLength = vectors[0].length; const resultData = Array(resultLength).fill(0); for (const vec of vectors) { vec.data.forEach((val, idx) => { resultData[idx] += val; }); } return { length: resultLength, data: resultData } as Vector<LengthT>; } // ✅ 合法调用:所有向量长度均为2 const vector2Sum = addAll(vector2a, vector2b, vector2c); // ❌ 类型报错:Vector<3>无法匹配Vector<2> const vector2badSum = addAll(vector2a, vector3);
原理说明
原来的...vectors: Vector<LengthT>[]写法存在漏洞:TypeScript会将LengthT推断为所有传入向量长度的联合类型(比如2 | 3),因此不同长度的向量也能通过类型检查。
修改后的[Vector<LengthT>, ...Vector<LengthT>[]]是元组类型,它的作用是:
- 以第一个传入的向量为基准,锁定
LengthT的具体值 - 强制后续所有参数必须严格匹配这个已锁定的
LengthT类型,否则直接抛出类型错误
从根源上确保了所有输入向量的长度类型完全一致。
内容的提问来源于stack exchange,提问作者theodop
相关产品推荐
相关产品推荐

