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

构建类型化SDK:TypeScript泛型约束函数参数且不捕获参数类型

如何让TypeScript函数的返回类型约束所有参数为该类型的子类型?

我正在构建一个类型化SDK,希望通过函数的返回类型来约束所有传入的参数,要求每个参数都符合返回类型,且参数之间的类型互不干扰。但当前实现遇到了问题:

function select<I extends R,R>(...items: I[]): R {
  return items[0];
}

const r: string | number = select('s', 1);
// 报错:Argument of type 'number' is not assignable to parameter of type 'string'.(2345)

当前表现:

  • ✅ TypeScript能正确推断R为string | number
  • ✅ 第一个参数可以接受string | number类型
  • ❌ 第二个参数只能接受string类型(因为I被推断为第一个参数的类型string)

解决方案

不需要额外的泛型参数I,直接将参数列表定义为Array<R>,这样每个参数都会被约束为R的子类型,且参数之间的具体类型互不影响:

function select<R>(...items: R[]): R {
  return items[0];
}

// 调用示例:无报错,参数类型互不干扰
const r: string | number = select('s', 1);
const r2: string = select('a', 'b');
const r3: number | boolean = select(5, true);

如果需要强制至少传入一个参数(避免空参数调用),可以调整函数签名:

function select<R>(first: R, ...rest: R[]): R {
  return first;
}

select(); // 报错:Expected at least 1 arguments, but got 0.(2554)

原理说明

去掉多余的I泛型后,TypeScript会根据返回类型R(由调用时的变量类型或显式指定的泛型决定)直接约束所有参数必须属于R类型,每个参数只需满足自身是R的子类型即可,不再受其他参数的类型推断影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:05:07