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

TypeScript如何从函数参数推断泛型参数A,无需手动传入?

TypeScript泛型推断优化问题

原代码示例

function runOnlyGivenActions<T extends object, A extends keyof T>(actions: readonly A[]) {
  // 处理actions逻辑
  console.log(actions);
  type T2 = Pick<T, A>;
}

interface Foo {
  hello(): string
  answer(): number;
  dontSelectMe(): void;
}

// 当前调用方式:需要手动传入第二个泛型参数
runOnlyGivenActions<Foo, "hello" | "answer">(["hello", "answer"])

背景说明

泛型参数A是T的成员筛选器,用来构建Pick<T,A>这类新类型。

runOnlyGivenActions函数不需要接收T的具体实例,只依赖T的类型契约。实际场景中,它会通过await import动态加载Node.js模块,获取实现T的具体类。

问题

能不能不用手动传入"hello" | "answer"作为第二个泛型参数,让TypeScript直接从传入的数组参数里自动推断出A的类型?理想调用方式是:

runOnlyGivenActions<Foo>(["hello", "answer"])

解决方案

可以通过调整泛型参数的约束和默认值实现自动推断,两种常用写法如下:

写法一:通过数组元素类型推导

function runOnlyGivenActions<T extends object>(actions: readonly (keyof T)[]) {
  // 处理actions逻辑
  console.log(actions);
  // 从数组元素类型推导筛选后的类型
  type T2 = Pick<T, typeof actions[number]>;
}

interface Foo {
  hello(): string
  answer(): number;
  dontSelectMe(): void;
}

// 直接传入T,数组元素自动校验并推断类型
runOnlyGivenActions<Foo>(["hello", "answer"]);

写法二:带默认值的泛型参数

function runOnlyGivenActions<T extends object, A extends keyof T = keyof T>(actions: readonly A[]) {
  // 处理actions逻辑
  console.log(actions);
  type T2 = Pick<T, A>;
}

interface Foo {
  hello(): string
  answer(): number;
  dontSelectMe(): void;
}

// 仅传入T,A会自动从数组元素推断具体类型
runOnlyGivenActions<Foo>(["hello", "answer"]);

第二种写法里,我们给A设置了默认值keyof T,但TypeScript会优先从传入的数组元素推断A的具体字面量类型,既保证了类型安全,又省去了手动指定A的麻烦。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:59:57