如何定义一个从抽象类扩展但永远不是顶级抽象类的类型?

时间:2018-11-07 13:04:39

标签: typescript

鉴于以下几点,您应该如何定义类型someTypeThatIncludeDecendantsOfA_ButNotA

abstract class A {}; 
class B extends A {
    constructor(){
        console.log("Creating B")
        super()
    }
 };

 class C extends A{};

 const myMap = new Map<string, someTypeThatIncludeDecendantsOfA_ButNotA>([ 
     ["B", B],
     ["C", C]
 ]);

 const Constructor = myMap.get("B");

 const obj = new Constructor();

我尝试将地图定义为new Map<string, typeof A>(),但随后出现错误提示Cannot create an instance of an abstract class。有道理。

也可以使用ExcludeExtract类型的游戏。但这也没什么用。我认为Java使用语法new Map<string, ? extends A>。 我一直在浏览文档,但似乎找不到任何类似的东西。

2 个答案:

答案 0 :(得分:2)

您可以使用构造函数签名代替实际的类:

const myMap = new Map<string, new () => A>([ 
    ["B", B],
    ["C", C]
]);

const Constructor = myMap.get("B");

const obj = new Constructor();

类型new () => A表示一个构造函数(由于new关键字),带有一个空的参数列表(()),该构造函数返回一个A的实例。任何具有默认构造函数的派生具体类都将满足此签名。

答案 1 :(得分:-1)

您可以创建一个接口并从该接口实现您的类A,并将您的typesomeTypeThatIncludeDecendantsOfA_ButNotA类型定义为接口

interface AA { .... }

abstract class A implements AA {}; 
class B extends A {
    constructor(){
        console.log("Creating B")
        super()
    }
 };

 class C extends A{};

 const myMap = new Map<string, AA>([ 
     ["B", B],
     ["C", C]
 ]);

 const Constructor = myMap.get("B");

 const obj = new Constructor();