typescript类类型-实例部分与静态部分详解

当这个咱们操做一个类接口的时候呢,咱们必需要知道类其实是有两个类型的:html

静态部分类型实例部分类型git

那么什么是实例部分与静态部分?typescript

咱们先看一下下面的代码,以官方的代码来说解:函数

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}
复制代码

实例部分类型

好比,在这个例子中,下面的接口中的currentTimesetTime就是实例的类型ui

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}
复制代码

实例类型一般是指那些经过Clock这个类实例出来的对象,要知足的部分。this

放到这里的意思就是:咱们经过new Clock()出来的实例,必需要知足拥有currentTimesetTime这两个属性。spa


静态部分类型

上面官方的例子中,class里的构造器是静态类型.net

constructor(h: number, m: number) { }
复制代码

咱们知道了什么是静态部分、什么是实例部分,那么二者在typescript有什么要注意的地方呢?code

当咱们的类,去实现一个构造器的接口(静态类型的接口)的,实际上会报错的。htm

换句话来讲,就是类不能直接去实现静态部分的接口,但能够直接实现实例类型的接口

咱们看一下下面的例子:

// 有new,就是有构造器签名,就是静态类型的接口,因此不能被类直接实现,会报错
interface ClockConstructor { 
    new (hour: number, minute: number);
}

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

报错是由于,当一个类去实现一个接口的时候,它其实是对实例部分作类型检查,好比currentTime或者setTime

而构造器存在于类的静态部分,因此是不会作检查的。

因此一个类相关的接口,就是实例部分的接口和构造器的接口(静态部分接口)


当一个类去实现一个实例部分接口的时候,就实现了对实例部分的类型检查,可是此时是没有对静态部分(构造器部分)进行类型检查的。

那么问题来了:

若是咱们就是要对类的静态部分,好比类的构造函数进行检查的话,怎么办呢?


如何用类类型接口(静态部分),何时用实例接口?

上面咱们说到当一个类去实现一个接口的时候,它其实是对实例部分作类型检查

因此若是咱们就是要对,静态部分去作检查的时候,就要像下面那样写。

// 静态部分接口
interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
// 实例部分接口
interface ClockInterface {
    tick();
}

// 第一个参数ctor的类型是接口 ClockConstructor,在这里就为类的静态部分指定须要实现的接口
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick toc");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
复制代码

在上面的代码中

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}
复制代码

上面的例子中,咱们建立了一个函数createClock

这个函数的第一个参数ctor的类型是接口 ClockConstructor,这样就实现了对类的静态部分实现类型检查


最后对inplements的理解对一点补充

class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}
复制代码

这里的implements ClockInterface 这个意思不是AnalogClock自己(类的静态部分)应该符合接口规则

而是类 AnalogClock 实例化出来的对象(类的实例部分)应该知足这个接口的规则


参考

typescript官方

blog

相关文章
相关标签/搜索