TypeScript中如何定义call signatures与construct signatures的函数实现
TypeScript 调用签名(call signatures)与构造签名(construct signatures)实现指南
为什么你的示例代码报错
你直接将调用签名和属性写在普通对象字面量中的写法不符合JS/TS的运行时规则:可调用的对象本质是函数实例,普通对象字面量无法被直接调用。正确的实现逻辑是先声明符合调用规则的函数,再给函数挂载额外属性。
调用签名(call signatures)
实现示例
type DescribableFunction = { description: string; (str: string): string; } // 1. 先定义符合调用签名参数、返回值要求的函数 const baseFn = (str: string) => str; // 2. 给函数挂载要求的额外属性 baseFn.description = 'df function description'; // 3. 赋值给对应类型的变量 const df: DescribableFunction = baseFn; // 正常使用 console.log(df.description, df('hello world'));
适用场景
调用签名主要用于需要给函数本身附加额外元信息的场景:
- 工具库导出的工具函数,挂载版本号、参数说明、使用示例等属性
- 事件系统的回调函数,挂载事件优先级、绑定的事件名、是否只触发一次等配置项
- 缓存类高阶函数返回的包装函数,挂载清空缓存、修改缓存阈值等附属方法
构造签名(construct signatures)
实现示例
构造签名对应的是可以用new关键字调用的构造函数,最常见的实现方式就是使用TS的class:
// 先定义构造函数返回的实例类型 type SomeObject = { value: string; } type SomeConstructor = { new (s: string): SomeObject; }; // 用class实现构造函数,天然符合构造签名约束 class MyClass { value: string; constructor(s: string) { this.value = s; } } const ctor: SomeConstructor = MyClass; // 正常使用 function fn(ctor: SomeConstructor) { return new ctor("hello"); } console.log(fn(ctor).value) // 输出 hello
如果用ES5风格的普通构造函数也可以实现,只需要做简单的类型断言即可。
适用场景
构造签名主要用于需要动态接收构造函数、生成实例的场景:
- 依赖注入容器的实例化逻辑,约束传入的构造函数参数与返回实例类型
- 工厂模式中,约束可传入的构造函数的参数规范
- 类装饰器的参数类型约束,确保装饰器接收的是符合要求的构造函数
内容的提问来源于stack exchange,提问作者Va_M
相关产品推荐
相关产品推荐

