Is it possible to enforce constructor parameter types with `extends` or `implements` in TypeScript?

拜拜、爱过 提交于 2019-12-24 10:55:14

问题


I've looked at all the following:

  1. Abstract constructor type in TypeScript

  2. How does `type Constructor<T> = Function & { prototype: T }` apply to Abstract constructor types in TypeScript?

  3. Abstract Constructor on Abstract Class in TypeScript

The third is the closest to what I'm looking for, but (unfortunately) the answer was more for the specific issue and less for the question title.

This is (in a simplified sense) what I'd like to be able to do:

abstract class HasStringAsOnlyConstructorArg {
  abstract constructor(str: string);
}

class NamedCat extends HasStringAsOnlyConstructorArg {
  constructor(name: string) { console.log(`meow I'm ${name}`); }
}

class Shouter extends HasStringAsOnlyConstructorArg {
  constructor(phrase: string) { console.log(`${phrase}!!!!!!`); }
}

const creatableClasses: Array<typeof HasStringAsOnlyConstructorArg> = [NamedCat, Shouter];
creatableClasses.forEach(
  (class: typeof HasStringAsOnlyConstructorArg) => new class("Sprinkles")
);

In the example above you can see that Shouter and NamedCat both use one single string for their constructor. They don't necessarily need to extend a class, they could implement an interface or something, but I really want to be able to hold a list of classes that require the exact same arguments to construct.

Is it possible to enforce a classes constructor parameter types with extends or implements in TypeScript?

EDIT: The "Possible Duplicate" appears to show how it is not possible to use new() in an interface for this purpose. Perhaps there are still other ways.


回答1:


You can do such enforcement on array itself, so it will allow only constructors with single string argument:

class NamedCat {
    constructor(name: string) { console.log(`meow I'm ${name}`); }
}

class Shouter {
    constructor(phrase: string) { console.log(`${phrase}!!!!!!`); }
}

type ConstructorWithSingleStringArg = new (args: string) => any;

const creatableClasses: Array<ConstructorWithSingleStringArg> = [NamedCat, Shouter];
creatableClasses.forEach(
    ctor => new ctor("Sprinkles")
);

Playground



来源:https://stackoverflow.com/questions/52350788/is-it-possible-to-enforce-constructor-parameter-types-with-extends-or-impleme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!