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

TypeScript中能否复用函数参数定义?求可行实现方案

答案

当然可以!现在TypeScript已经完全支持复用函数参数定义的需求了,而且有几种简洁的实现方式,正好匹配你想要的场景:

方法1:直接定义可复用的参数元组

这是最直观的方式,把你想要复用的参数结构定义成一个元组类型,然后在需要的地方直接引用:

import { EventEmitter } from 'events';

// 定义要复用的事件参数元组,明确标注每个参数的名称和类型
type FooEventArgs = [x: string, y: number];

class MyEmitter extends EventEmitter {
  // 在emit中使用元组
  emit(event: "foo", ...args: FooEventArgs): boolean;
  // 保留EventEmitter原有的通用签名
  emit(event: string | symbol, ...args: any[]): boolean {
    return super.emit(event, ...args);
  }

  // 在on的回调中复用同一个元组
  on(event: "foo", listener: (...args: FooEventArgs) => void): this;
  // 保留通用签名
  on(event: string | symbol, listener: (...args: any[]) => void): this {
    return super.on(event, listener);
  }
}

这种方式的好处是结构清晰,一眼就能看出参数的定义,而且完全支持任意数量的参数,解决了你提到的早期方案只能支持0或1个参数的问题。

方法2:从已有函数签名中提取参数(内置工具类型)

如果你已经有了某个函数的定义(比如先写了emit,想复用它的参数到on里),可以用TypeScript内置的Parameters工具类型来提取参数类型,甚至可以进一步筛选出你需要的部分:

import { EventEmitter } from 'events';

class MyEmitter extends EventEmitter {
  // 先定义emit的特定签名
  emit(event: "foo", x: string, y: number): boolean;
  emit(event: string | symbol, ...args: any[]): boolean {
    return super.emit(event, ...args);
  }

  // 提取emit("foo")的参数,排除第一个event参数
  type FooEventArgs = Parameters<typeof MyEmitter["emit"]> extends [string, ...infer Args] ? Args : never;

  // 在on中复用提取出的参数
  on(event: "foo", listener: (...args: FooEventArgs) => void): this;
  on(event: string | symbol, listener: (...args: any[]) => void): this {
    return super.on(event, listener);
  }
}

这里Parameters<typeof MyEmitter["emit"]>会提取emit函数的所有参数类型组成的元组,我们再通过条件类型infer把第一个event参数排除,只保留后面的业务参数。

关于你提到的TS议题

你关注的那些早期议题确实推动了TypeScript类型系统的完善,现在TypeScript 3.1及以上版本已经内置了Parameters、ReturnType等工具类型,完全覆盖了你想要的参数复用场景,不需要依赖复杂的自定义类型操作了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:02:16