让我们从示例中的简单界面开始:
interface ClockInterface {
tick();
}
这个接口定义了这个类型的一个实例包含tick方法,这两个实现了这个接口:
class MyClock implements ClockInterface {
public tick(): void {
console.log("tick");
}
}
let a: ClockInterface = new MyClock();
let b: ClockInterface = {
tick: () => console.log("tick")
}
这很简单,因为类实现与其他 OO 语言中的相同,第二个实现并不简单,但对于 javascript 开发人员来说应该很容易理解。
这很好用!但是如果我想获得一个类的构造函数作为我的函数的参数会发生什么?
这行不通:
function constructorClock(ctor: ClockInterface): ClockInterface {
return new ctor();
}
这里的参数是ClockInterface 的实例而不是类(/构造函数),所以为了处理这种情况,我们可以为类本身定义一个接口而不是实例:
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
现在我们可以有这个功能了:
function constructorClock(ctor: ClockConstructor): ClockInterface {
return new ctor(3, 5);
}
这些构建器接口给我们的另一个问题是定义静态类成员/方法的能力,一个很好的例子是ArrayConstructor(它是lib.d.ts的一部分):
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>;
prototype: Array<any>;
}
(定义取决于您使用的是ES5 还是ES6 目标,这是ES5 之一)。
如您所见,接口定义了不同的构造函数签名,prototype 和 isArray 函数,您可以像这样使用它:
Array.isArray([1,2])
如果您没有能力为类本身(而不是实例)提供接口,那么您将无法使用此 isArray 函数,因为这是错误的:
let a = [];
a.isArray(3);
DigitalClock 和AnalogClock 类通过tick 方法实现ClockInterface(即它们的实例 具有此方法),但它们实现了ClockConstructor 接口他们的constructor 函数与new 一起使用,它返回一个ClockInterface 的实例。
希望这有助于澄清它
编辑
构造函数当然不会返回interface,它会返回一个实现了ClockInterface接口的实例。
也许这会让事情变得更容易:
class BaseClock {
protected hour: number;
protected minute: number;
constructor(hour: number, minute: number) {
this.hour = hour;
this.minute = minute;
}
public tick() {
console.log(`time is: ${ this.hour }:${ this.minute }`);
}
}
class DigitalClock extends BaseClock {
constructor(hour: number, minute: number) {
super(hour, minute);
}
tick() {
console.log("digitial");
super.tick();
}
}
class AnalogClock extends BaseClock {
constructor(hour: number, minute: number) {
super(hour, minute);
}
tick() {
console.log("analog");
super.tick();
}
}
interface ClockConstructor {
new (hour: number, minute: number): BaseClock;
}
function createClock(ctor: ClockConstructor, hour: number, minute: number): BaseClock {
return new ctor(hour, minute);
}
我们现在只使用类而不是接口,这样更有意义吗?
语法:new (hour: number, minute: number): ClockInterface 定义了一个构造函数,this:
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}
createClock(DigitalClock, 12, 17);
就像:
function createDigitalClock(hour: number, minute: number): ClockInterface {
return new DigitalClock(hour, minute);
}
createDigitalClock(12, 17);
new ctor(hour, minute);(其中ctor 是ClockConstructor)类似于new DigitalClock(hour, minute)(只是更通用)。