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

art*_*.sw 56 constructor types class typescript

我如何声明一个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这种class类型不起作用,无论如何它都太普遍了.

art*_*.sw 51

来自typescript接口的解决方案参考:

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);
Run Code Online (Sandbox Code Playgroud)

所以前面的例子变成了:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @pixelpax虽然它没有意义,因为`typeof Animal`只是字符串``function``.任何课程都会满足这一要求,而不仅仅是动物学家. (9认同)
  • 我只想补充一点,这个解决方案对我不起作用,如果你想使用一个非零数量的参数的构造函数,它将无法工作.让我永远弄清楚为什么这个例子有效但我的代码没有.经过几个小时的搜索后我发现的东西是使用`AnimalClass:typeof Animal`.这将用于动态加载给定类的子类. (4认同)
  • `虽然它没有意义,因为 typeof Animal 只是字符串“函数”` - 在纯 JS 中,是的。在 TypeScript 类型注释中,没有。`typeof X` 表示符号 X 的类型,无论它是什么,并且正在由编译器静态处理。 (4认同)
  • @pixelpax你可以像这样定义一个非零参数构造函数:`new(... args:any []):Animal` (2认同)

gap*_*ton 15

像那样:

class Zoo {
    AnimalClass: typeof Animal;

    constructor(AnimalClass: typeof Animal ) {
        this.AnimalClass = AnimalClass
        let Hector = new AnimalClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

要不就:

class Zoo {
    constructor(public AnimalClass: typeof Animal ) {
        let Hector = new AnimalClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

typeof Class是类构造函数的类型.它比自定义构造函数类型声明更可取,因为它正确处理静态类成员.

  • “ typeof Animal”是TypeScript类型注释,可“返回” Animal构造函数的类型。它不返回字符串。 (3认同)
  • 在尝试更正答案之前,在打字稿操场中运行有问题的代码并查阅文档 (https://www.typescriptlang.org/docs/handbook/classes.html) 总是一个好主意。永远不会痛:)。 (2认同)
  • 但它不适用于抽象类。 (2认同)

Ale*_*leC 9

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

构造函数类型可以定义为:

 type AConstructorTypeOf<T> = new (...args:any[]) => T;

 class A { ... }

 function factory(Ctor: AConstructorTypeOf<A>){
   return new Ctor();
 }

const aInstance = factory(A);
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,使用这种方法你会失去构造函数参数的类型检查。 (9认同)

Nen*_*nad 5

我不确定最初问这个问题时在TypeScript中是否可行,但是我的首选解决方案是使用泛型

class Zoo<T extends Animal> {
    constructor(public readonly AnimalClass: new () => T) {
    }
}
Run Code Online (Sandbox Code Playgroud)

这样就可以变量penguinlion推断具体类型PenguinLion甚至可以推断出TypeScript智能感知。

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.
Run Code Online (Sandbox Code Playgroud)

  • +1这个答案是[官方文档](https://www.typescriptlang.org/docs/handbook/2/generics.html#using-class-types-in-generics)建议的。 (3认同)