类的静态和实例方面的区别

Shi*_*kur 14 javascript typescript

当我遇到类类型时,我试图理解Typescript中的界面主题,我从官方文档中获取此代码

interface ClockConstructor {
    new (hour: number, minute: number);
}

class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
Run Code Online (Sandbox Code Playgroud)

我可以理解,这Clock与签名无法匹配, new (hour: number, minute: number);这就是我们在那里得到错误的原因.

但在文档中,解释是我无法理解的.它是这样的:

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

任何解释将不胜感激.

Nit*_*mer 8

接口声明实例具有的方法/成员,而不是实现类具有的方法/成员.

例如,检查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>;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Array存在于任何数组实例上的has方法/成员:

let a = [];
a.push(1, 2, 3);
console.log(a.length);
Run Code Online (Sandbox Code Playgroud)

但是ArrayConstructorArray自己存在的成员/方法:

console.log(Array. prototype);
console.log(Array.isArray(9));
Run Code Online (Sandbox Code Playgroud)

构造函数是"静态"部分的一部分,这就是它们被声明的原因ArrayConstructor.
例如,如果在接口上声明构造函数,则在实现该接口时会遇到问题:

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

class MyClass implements MyInterface {
    constructor() {}

    getName() { return "name" };
}
Run Code Online (Sandbox Code Playgroud)

错误:

类'MyClass'错误地实现了接口'MyInterface'.属性"构造函数"的类型是不兼容的.类型'Function'不能分配给'()=> void'.类型'Function'不提供签名'():any'的匹配.


Die*_*erg 5

在获取实例之前,您需要使用静态端 constructor , 来获取实例。new无论如何,您不需要在您的界面中,您的类本身是类型化的,因​​此打字稿知道它必须通过构造函数传递的任何参数。

new如果您想传递 afunctionclass在实例化之前必须满足某些构造函数要求,您可以利用带有类型的接口。

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);
Run Code Online (Sandbox Code Playgroud)

事实上,TypeScript 类是 JavaScript 中的一个常规函数,当您不在new它前面使用时它是静态的。这是文档所指的。

// static side
function Person() {

}

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

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

var person = new Person() // instance side
Run Code Online (Sandbox Code Playgroud)

另请参阅此答案