我是 typescript 的新手,我一直在理解构造函数接口(interface)以及它们的类型检查方式。这是文档中的一个片段:
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick();
}
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 tock");
}
}
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
这是文档对上述代码的描述:
Because createClock’s first parameter is of type ClockConstructor, in createClock(AnalogClock, 7, 32), it checks that AnalogClock has the correct constructor signature.
现在这实际上意味着 DigitalClock 类或 AnalogClock 类具有由 ClockConstructor 接口(interface)定义的类型。如何?它是一个类,接口(interface)描述了一个构造函数。
请问有人要吗?
最佳答案
让我们从示例中的简单界面开始:
interface ClockInterface {
tick();
}
该接口(interface)定义了该类型的实例包含tick
方法,这两个实现了该接口(interface):
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)而不是实例:
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
现在我们可以拥有这个功能:
function constructorClock(ctor: ClockConstructor): ClockInterface {
return new ctor(3, 5);
}
这些构建器接口(interface)给我们带来的另一个问题是能够定义静态类成员/方法,一个很好的例子是 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
目标)。
如您所见,接口(interface)定义了不同的构造函数签名,prototype
和 isArray
函数,您可以像这样使用它:
Array.isArray([1,2])
如果您没有能力为类本身(而不是实例)提供接口(interface),那么您将无法使用此 isArray
函数,因为这是错误的:
let a = [];
a.isArray(3);
DigitalClock
和 AnalogClock
类通过 tick
方法(即它们的 instances 有这个方法),但是他们用他们的 constructor
函数实现了 ClockConstructor
接口(interface),这个函数与 new
一起使用,它返回ClockInterface
的实例。
希望这有助于澄清它
编辑
构造器当然不会返回一个interface
,它返回一个实现了这个ClockInterface
接口(interface)的实例。
也许这会让事情变得更容易:
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);
}
我们现在只使用类而不是接口(interface),这样更有意义吗?
语法: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)
(只是更通用)。
关于javascript - 理解 typescript 中的构造函数接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37292534/