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

如何基于TypeScript泛型参数确定函数另一参数的正确类型?

问题分析

你遇到的问题是TypeScript无法在函数内部通过input的类型判断自动推导options的对应类型,核心原因在于泛型参数T是函数调用时确定的类型,函数内部的类型守卫(比如typeof input === 'number')只能缩小input的类型范围,但无法反向约束泛型T的具体类型,因此条件类型T extends string ? OptionsString : OptionsNumber不会跟着input的类型判断同步缩小。

解决方案

可以通过两种方式解决这个问题:

方案一:使用函数重载

函数重载能明确指定不同输入类型对应的参数组合,让TypeScript直接关联input和options的类型:

type OptionsNumber = {
  numberProp: number
}

type OptionsString = {
  stringProp: string
}

// 重载签名
export function test(input: number | null | undefined, options?: OptionsNumber): void;
export function test(input: string | null | undefined, options?: OptionsString): void;

// 实现签名
export function test(
  input: string | number | null | undefined,
  options?: OptionsString | OptionsNumber
): void {
  if (typeof input === 'number') {
    // 此时TypeScript能正确推断options为OptionsNumber
    console.log(options?.numberProp);
  } else if (typeof input === 'string') {
    console.log(options?.stringProp);
  }
}

方案二:使用联合类型的参数元组

将input和options打包成一个联合类型的元组,让TypeScript通过元组的关联性来推导类型:

type OptionsNumber = {
  numberProp: number
}

type OptionsString = {
  stringProp: string
}

type TestParams = 
  | [input: number | null | undefined, options?: OptionsNumber]
  | [input: string | null | undefined, options?: OptionsString]

export const test = (...[input, options]: TestParams): void => {
  if (typeof input === 'number') {
    console.log(options?.numberProp);
  } else if (typeof input === 'string') {
    console.log(options?.stringProp);
  }
}
为什么原代码不生效?

原代码中的泛型条件类型是基于调用时的泛型参数T来计算options的类型,而不是基于函数内部input的实际类型。比如当调用test(123, {numberProp: 456})时,T被推断为number,此时options的类型是OptionsNumber;但函数内部的typeof input === 'number'只是确认了input的类型是number,但TypeScript不会把这个判断和泛型T的类型绑定,所以无法推断options的具体类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:26:13