當這個咱們操做一個類接口的時候呢,咱們必需要知道類其實是有兩個類型的: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) { }
}
複製代碼
好比,在這個例子中,下面的接口中的currentTime
、setTime
就是實例的類型。ui
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
複製代碼
實例類型一般是指那些經過Clock
這個類實例出來的對象,要知足的部分。this
放到這裏的意思就是:咱們經過new Clock()
出來的實例,必需要知足擁有currentTime
、setTime
這兩個屬性。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 實例化出來的對象(類的實例部分)應該知足這個接口的規則