如何在 TypeScript 中正确使用 Function 的构造签名

  • 本文关键字:Function TypeScript typescript
  • 更新时间 :
  • 英文 :


我正在阅读TS文档,当我阅读更多关于函数的内容时,我不理解下面的代码,以及如何在实际开发中使用它。有什么例子吗?

interface CallOrConstruct {
new (s: string): Date;
(n?: number): number;
}

您在这里看到的是一个单独的对象,它具有不同的行为,这取决于您是否使用new调用它。这是Javascript能够做到的,但可能会导致代码混乱;您可能只会很少看到这种签名,或者在将非常旧或灵活的Javascript库用于Typescript时才会看到这种签名。

(从技术上讲,行为不必不同:敏感对象可能在有或没有new的情况下都可以调用,具有相同的整体行为,并且需要调用构造签名。然而,这种刻意的灵活性仍然不常见。谢谢@kaya3!(


您的代码段出现在函数的更多信息中的文本下:

一些对象,如JavaScript的Date对象,可以在有或没有new的情况下调用。您可以任意组合相同类型的调用和构造签名:

这是对内置Date对象的引用,该对象在MDN:上有以下文本

Date()

作为函数调用时,返回当前日期和时间的字符串表示,与new Date().toString()完全相同。

new Date()

作为构造函数调用时,返回一个新的Date对象。

console.log(typeof Date())      // string
console.log(typeof new Date())  // object

如上所述,一个Function对象同时具有这两种用途是非常罕见的:您通常会看到一个函数/类被故意调用为一个或另一个,但不是两者都有。然而,因为可以在Javascript中完成(甚至可以在内置对象中完成(,所以TypeScript能够表示在两种调用样式中都能工作的对象是很重要的。

interface CallOrConstruct {
new (s: string): Date;      // construct
(n?: number): number;       // call
}
// construct
let object: Date = new CallOrConstruct("optional string s");
// call
let myNumber: number = CallOrConstruct(/* n= */ 42);

您可能永远不需要键入这样的接口,特别是如果类使用classconstructor,函数使用function(或其他正常函数声明(。只有当您试图声明TypeScript不理解的类型(如在外部Javascript库的.d.tsTypeScript声明文件中(,或者如果您试图编写一个既聪明又令人困惑的TypeScript对象,可以同时使用这两种方法时,才需要这样做。就我自己而言,我没有理由写这样的声明,尽管我在图书馆和他们的打字员那里读过一些。