TS中`Function`、`CallableFunction` 和 `NewableFunction`的函数区别

6 阅读3分钟

在 TypeScript 中,FunctionCallableFunctionNewableFunction 都是用来描述“函数”或“可调用对象”的内置接口,但它们各自的侧重点和使用场景有所不同。

简单来说,它们分别代表了:任意函数只能被调用的函数只能用 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 类型,以保证代码的类型安全。