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

TypeScript中如何检查函数参数是否为可选参数?

判断函数参数是否为可选类型

我们先明确核心问题:通过Parameters<typeof saySomething>[0]获取到的参数类型是string | undefined,但这个类型无法区分它是来自可选参数thingToSay?: string,还是来自必填的联合类型参数thingToSay: string | undefined。因此需要从函数的参数元组结构本身入手,实现一个IsOptional工具类型来判断指定位置的参数是否为可选。

实现IsOptional工具类型

下面是一种可行的实现方式,通过对比参数元组在指定位置变为必填后的兼容性来判断是否可选:

// 替换元组指定索引位置的类型为新类型
type ReplaceIndex<T extends any[], Index extends number, NewType> =
  T extends [...infer Head, infer _]
    ? Head['length'] extends Index
      ? [...Head, NewType]
      : ReplaceIndex<Head, Index, NewType>
    : never;

// 判断函数指定索引的参数是否为可选
type IsOptional<Fn extends (...args: any[]) => any, Index extends number> =
  Parameters<Fn> extends ReplaceIndex<Parameters<Fn>, Index, Exclude<Parameters<Fn>[Index], undefined>>
    ? false
    : true;

使用示例

针对你的示例函数:

function saySomething(thingToSay?: string) {
  console.log(thingToSay || 'Hello');
}

// 判断第0位参数是否可选,结果为true
type ThingToSayIsOptional = IsOptional<typeof saySomething, 0>;

再对比必填的联合类型参数:

function saySomethingRequired(thingToSay: string | undefined) {
  console.log(thingToSay || 'Hello');
}

// 判断第0位参数是否可选,结果为false
type ThingToSayIsOptional2 = IsOptional<typeof saySomethingRequired, 0>;

原理说明

  1. ReplaceIndex工具类型会将参数元组中指定索引的位置,替换为排除undefined后的类型(也就是该参数的必填版本)。
  2. 如果原参数元组能赋值给这个“必填版本元组”,说明原参数本身就是必填的(即使允许传入undefined,但不能省略),返回false。
  3. 如果不能赋值,说明原参数是可选的(可以省略,因此无法适配必填版本的元组),返回true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:49:50