You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>[]]是元组类型,它的作用是:

  1. 以第一个传入的向量为基准,锁定LengthT的具体值
  2. 强制后续所有参数必须严格匹配这个已锁定的LengthT类型,否则直接抛出类型错误

从根源上确保了所有输入向量的长度类型完全一致。


内容的提问来源于stack exchange,提问作者theodop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 08:20:03