打字稿中的类构造函数类型?

时间:2016-09-21 10:43:07

标签: class typescript types constructor

如何声明class类型,以便确保对象是通用类的构造函数?

在以下示例中,我想知道应该向AnimalClass提供哪种类型,以便它可以是PenguinLion

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类型不起作用,反正过于笼统。

4 个答案:

答案 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智能感知中,变量penguinlion也会推断出具体类型PenguinLion

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);