在 TypeScript 中,Function、CallableFunction 和 NewableFunction 都是用来描述“函数”或“可调用对象”的内置接口,但它们各自的侧重点和使用场景有所不同。
简单来说,它们分别代表了:任意函数、只能被调用的函数 和 只能用 new 调用的构造函数。
下面为你详细介绍这三者的区别:
1. Function(任意函数)
Function 是 TypeScript 中最宽泛的函数类型。它代表了 JavaScript 中所有的函数(普通函数、箭头函数、方法等)。
- 特点:它的定义范围非常广,任何函数都可以被赋值给
Function类型。 - 缺点:由于它过于宽泛,使用它会丢失具体的参数和返回值类型信息(通常会被推断为
any),因此在现代 TypeScript 开发中,不建议直接使用Function来声明具体的函数类型,这会失去 TS 类型检查的意义。
2. CallableFunction(可调用函数)
它专门用来描述那些只能通过普通方式调用即 fn() 的函数
- 核心场景:在日常开发中,我们定义的绝大多数普通函数、箭头函数都属于这一类。
- 类型写法:在 TypeScript 中,我们通常不会直接写
CallableFunction这个单词,而是使用函数类型表达式或调用签名来描述它:- 函数类型表达式:
(a: string) => void(描述一个带参数且无返回值的函数)。 - 调用签名(Call Signature):在接口或对象类型中,使用
(arg: number): string的形式来描述。调用签名的强大之处在于,它允许这个函数对象除了能被调用外,还能拥有自己的属性。 函数签名介绍
- 函数类型表达式:
// 使用调用签名描述一个带属性的可调用函数
type MyCallable = {
(name: string): void; // 调用签名:可以像函数一样调用
version: string; // 额外属性
};
const myFunc: MyCallable = (name) => console.log(name);
myFunc.version = "1.0.0";
3. NewableFunction(可构造函数)
它专门用来描述那些必须通过 new 关键字来调用的函数,也就是我们常说的构造函数。
- 核心场景:用于描述类(Class)或者通过
function定义并打算用new实例化的构造函数。 - 类型写法:同样,我们通常通过**构造签名(Construct Signature)**来描述它,即在调用签名的前面加上
new关键字。
// 使用构造签名描述一个构造函数
type MyNewable = {
new (name: string): { name: string }; // 构造签名:必须用 new 调用
};
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
const createInstance = (ctor: MyNewable) => {
return new ctor("小明"); // 在这里使用 new 关键字实例化
};
const p = createInstance(Person);
总结对比
| 类型概念 | 核心特征 | 常见 TS 写法/描述 |
|---|---|---|
| Function | 任意函数,范围最广,类型不安全 | Function (不推荐直接使用) |
| CallableFunction | 只能通过 fn() 调用的普通函数 | (arg: string) => void 或调用签名 (arg): void |
| NewableFunction | 只能通过 new fn() 调用的构造函数 | 构造签名 new (arg: string) => Object |
在日常的 TypeScript 业务开发中,你绝大多数时候接触到的都是 CallableFunction(普通函数类型)和 NewableFunction(构造签名),建议尽量少用宽泛的 Function 类型,以保证代码的类型安全。