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

时间:2016-09-07 06:34:52

标签: javascript typescript

我正在尝试理解Typescript中的界面主题 当我遇到类型时,我从official docs

获得了此代码
interface ClockConstructor {
    new (hour: number, minute: number);
}

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

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

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

  

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

任何解释都将不胜感激。

2 个答案:

答案 0 :(得分: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>;
}

如您所见,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" };
}

错误:

  

Class'MyClass'错误地实现了接口'MyInterface'。类型   属性'构造函数'是不兼容的。类型'功能'不是   可分配给'()=&gt;类型无效”。类型'功能'不提供匹配   签名'():any'。

答案 1 :(得分:4)

在获得实例之前,您需要使用静态端new来获取实例。无论如何,你的界面都不需要new,你的类本身就是自己键入的,因此打字稿知道它必须传递给构造函数的任何参数。

如果要在实例化之前传递必须满足某些构造函数要求的functionclass,则可以使用类型为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); 的接口。

new

事实上,TypeScript类是JavaScript中的常规函数​​,当您不在其前面使用// static side function Person() { } Person.SayHi = function () { return 'Hello'; } console.log(Person.SayHi()); // static function.. var person = new Person() // instance side 时它是静态的。这是文档所指的。

{{1}}

See also this answer