【问题标题】:Typescript 2.4.1 and stricter generics breaking typeof/inheritanceTypescript 2.4.1 和更严格的泛型打破 typeof/inheritance
【发布时间】:2017-07-30 17:06:07
【问题描述】:

我有这个打字稿代码,它使用了过去在打字稿 2.3 下工作的泛型,但现在在打字稿 2.4.1 更严格的打字强制下打破了。

我写了这个最小的代码 sn-p 来演示这个问题:

class A {}
class B extends A {}
function helloA(clazz: typeof A) {}
helloA(B); // fine

class C<T> {
    private c: T;
};
class D extends C<string> {}
function helloC(clazz: typeof C) {}
helloC(D); // breaks

来自 tsc 2.4.1 的错误如下:

test.ts(11,8): error TS2345: Argument of type 'typeof D' is not assignable to parameter of type 'typeof C'.
  Type 'D' is not assignable to type 'C<T>'.
    Types of property 'c' are incompatible.
      Type 'string' is not assignable to type 'T'.

所以 helloA(B) 可以正常工作,而以前可以正常工作的 helloC(D) 现在会中断(如果我在我的 tsconfig 中添加 "noStrictGenericChecks": true ,它当然可以编译)。

如果我删除 private c: T; 部分,它也会编译。请注意,在我的实际代码中,这个类成员确实存在,但我扩展的类是来自外部库,所以我不能删除它,此外,我希望它与它一起编译。

有没有办法让这段代码编译并保留字符串类型?

【问题讨论】:

    标签: typescript generics typeof


    【解决方案1】:

    我不知道有什么方法可以使用typeof C 不会将{} 推断为泛型类型参数。幸运的是,您可以以不同的方式引用类构造函数:

    type Constructor<T> = {
      new(...args: any[]): T;
      readonly prototype: T;
    }
    
    function helloC<T>(clazz: Constructor<C<T>>) { }
    helloC(D);
    

    通过检查对helloC 的调用,您可以看到它将string 推断为类型参数。

    希望有帮助!

    【讨论】:

    • 这是一个非常聪明的解决方案,而且效果很好!非常感谢!
    猜你喜欢
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2020-08-30
    • 2022-01-26
    • 2019-07-16
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多