当这个咱们操做一个类接口的时候呢,咱们必需要知道类其实是有两个类型的: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 实例化出来的对象(类的实例部分)应该知足这个接口的规则