类的静态端和实例端之间的区别

问题描述 投票:0回答:2

我正在尝试理解 Typescript 中的界面主题 当我遇到类类型时,我从官方文档

得到了这段代码
interface ClockConstructor {
    new (hour: number, minute: number);
}

class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

我可以理解

Clock
与签名
new (hour: number, minute: number);
不匹配,这就是我们在那里收到错误的原因。

但是文档中的解释是我无法理解的。事情是这样的:

这是因为当类实现接口时,仅检查类的实例端。由于构造函数位于静态端,因此它不包含在此检查中。

任何解释将不胜感激。

javascript typescript
2个回答
10
投票

接口声明实例必须具有的方法/成员,不包括实现类具有的内容。

例如检查 ArrayArrayConstructor 声明:

interface Array<T> {
    length: number;
    toString(): string;
    toLocaleString(): string;
    push(...items: T[]): number;
    pop(): T | undefined;
    ...
    [n: number]: T;
}

interface ArrayConstructor {
    new (arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
    (arrayLength?: number): any[];
    <T>(arrayLength: number): T[];
    <T>(...items: T[]): T[];
    isArray(arg: any): arg is Array<any>;
    readonly prototype: Array<any>;
}

如您所见,

Array
具有存在于任何数组实例上的方法/成员:

let a = [];
a.push(1, 2, 3);
console.log(a.length);

但是

ArrayConstructor
具有
Array
本身存在的成员/方法:

console.log(Array. prototype);
console.log(Array.isArray(9));

构造函数是“静态”部分的一部分,这就是为什么它们在

ArrayConstructor
中声明。
例如,如果您在接口上声明构造函数,那么您在实现该接口时就会遇到问题:

interface MyInterface {
    constructor();
    getName(): string;
}

class MyClass implements MyInterface {
    constructor() {}
    
    getName() { return "name" };
}

错误:

类“MyClass”错误地实现了接口“MyInterface”。类型 属性“构造函数”不兼容。类型“函数”不是 可分配给类型“() => void”。类型“函数”不提供匹配项 签名“():任意”。


5
投票

在获取实例之前,您需要使用静态端

constructor
来获取实例。无论如何,你的界面中不需要
new
,你的类本身就是类型化的,因此打字稿知道它必须沿着构造函数传递的任何参数。

如果您想传递必须满足某些构造函数要求才能实例化的

new
function
,则可以利用类型为
class
的接口的优势。

interface IFoo {
   new(title: string);
}

function MyFunction(ctor: IFoo, title:string) {
   return new ctor(title);
}

class MyClass {
   constructor(public title: string) {}
}

class MySecondClass {
   constructor(public title: string) {}
}

var myClass = MyFunction(MyClass, 'title');
var mySecondClass = MyFunction(MySecondClass, 'title');

console.log(myClass.title, mySecondClass.title);

事实上,TypeScript 类是 JavaScript 中的常规函数,当您不在其前面使用

new
时,它是静态的。这是文档所指的。

// static side
function Person() {

}

Person.SayHi = function () {
  return 'Hello';
}

console.log(Person.SayHi()); // static function..

var person = new Person() // instance side

另请参阅此答案

© www.soinside.com 2019 - 2024. All rights reserved.