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

相關文章
相關標籤/搜索