首页 > 解决方案 > TypeScript:工厂方法 - 不正确的扩展,返回的类型不兼容

问题描述

再次花费太多时间在正确的类型上,并且想知道这样的事情是否可能没有编译器抛出不正确的基类扩展的错误,即使它正确识别返回的类型(见最后一行):

class Parent {
    static create<T extends Parent>(Cls: new () => T): T {
        return new Cls();
    }
}

class Child extends Parent {
    static create() {
        return super.create(Child);
    }
}

const inst = Child.create();    // correct type of "Child"

游乐场链接

抛出的错误:

Class static side 'typeof Child' incorrectly extends base class static side 'typeof Parent'.
  The types returned by 'create(...)' are incompatible between these types.
    Type 'Child' is not assignable to type 'T'.
      'Child' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Parent'.

如何告诉编译器,返回的类型将与 Cls 参数的类型相同?我是 TS 的新手,但我会说我不需要泛型,因为我将创建的对象的类型作为参数传递,所以我确切地知道类型。

标签: typescript-generics

解决方案


在这里,TypeScript 编译器试图匹配这两种static方法。即使您确保返回类型匹配,Typescript 也不确定。你可以这样想,每次不同的调用Parent::create都会在Parent. 其中一个为Child延伸Parent,但可能AnotherChild从 延伸Parent。并且Child不能分配给其他子类型,这就是编译器抱怨的原因。

我相信删除通用代码并执行以下操作会更容易 -

class Parent {
    static create(Cls: new () => Parent): Parent {
        return new Cls();
    }
}

class Child extends Parent {
    static create() : Child {
        return super.create(Child);
    }
}

const inst = Child.create();    // correct type of "Child"

正如Child已经从 扩展而来的那样ParentChild::create这里现在完全有效。


推荐阅读