如何声明class
类型,以便确保对象是通用类的构造函数?
在以下示例中,我想知道应该向AnimalClass
提供哪种类型,以便它可以是Penguin
或Lion
:
class Animal {
constructor() {
console.log("Animal");
}
}
class Penguin extends Animal {
constructor() {
super();
console.log("Penguin");
}
}
class Lion extends Animal {
constructor() {
super();
console.log("Lion");
}
}
class Zoo {
AnimalClass: class // AnimalClass could be 'Lion' or 'Penguin'
constructor(AnimalClass: class) {
this.AnimalClass = AnimalClass
let Hector = new AnimalClass();
}
}
当然,class
类型不起作用,反正过于笼统。
答案 0 :(得分:46)
来自typescript interfaces reference的解决方案:
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);
所以上一个例子变成了:
interface AnimalConstructor {
new (): Animal;
}
class Animal {
constructor() {
console.log("Animal");
}
}
class Penguin extends Animal {
constructor() {
super();
console.log("Penguin");
}
}
class Lion extends Animal {
constructor() {
super();
console.log("Lion");
}
}
class Zoo {
AnimalClass: AnimalConstructor // AnimalClass can be 'Lion' or 'Penguin'
constructor(AnimalClass: AnimalConstructor) {
this.AnimalClass = AnimalClass
let Hector = new AnimalClass();
}
}
答案 1 :(得分:7)
就像那样:
class Zoo {
AnimalClass: typeof Animal;
constructor(AnimalClass: typeof Animal ) {
this.AnimalClass = AnimalClass
let Hector = new AnimalClass();
}
}
或者只是:
class Zoo {
constructor(public AnimalClass: typeof Animal ) {
let Hector = new AnimalClass();
}
}
typeof Class
是类构造函数的类型。它比自定义构造函数类型声明更可取,因为它正确处理静态类成员。
这是TypeScript docs的相关部分。搜索typeof
。作为TypeScript类型注释的一部分,它意味着"给我一个名为Animal"的符号类型。这是我们案例中类构造函数的类型。
答案 2 :(得分:6)
我不确定最初提出该问题时是否可以在 TypeScript 中实现,但是我的首选解决方案是使用泛型:
class Zoo<T extends Animal> {
constructor(public readonly AnimalClass: new () => T) {
}
}
这样,即使在TypeScript智能感知中,变量penguin
和lion
也会推断出具体类型Penguin
或Lion
。
const penguinZoo = new Zoo(Penguin);
const penguin = new penguinZoo.AnimalClass(); // `penguin` is of `Penguin` type.
const lionZoo = new Zoo(Lion);
const lion = new lionZoo.AnimalClass(); // `lion` is `Lion` type.
答案 3 :(得分:1)
如何声明类类型,以确保对象是常规类的构造函数?
构造函数类型可以定义为:
type AConstructorTypeOf<T> = new (...args:any[]) => T;
class A { ... }
function factory(Ctor: AConstructorTypeOf<A>){
return new Ctor();
}
const aInstance = factory(A);