【问题标题】:TypeScript: wrapper for generic class implementationTypeScript:通用类实现的包装器
【发布时间】:2021-09-17 07:35:33
【问题描述】:

为什么在 TypeScript 中不能进行以下操作?

abstract class Generic<T> {
  // ...
}

class Specific1 extends Generic<string> {
  // ...
}

class Specific2 extends Generic<number> {
  // ...
}

// this is where stuff goes wrong, compiler wants me to provide generic type arguments
//                                     |
//                                     ˅
abstract class Wrapper<T extends Generic> {
  // ...
}

class Wrapper1 extends Wrapper<Specific1> {
  // ...
}


class Wrapper2 extends Wrapper<Specific2> {
  // ...
}

使用Wrapper 泛型类行,我想表达我只想让类进入Wrapper 作为“专门实现”Generic 的泛型类型,即Specific1Specific2 , 在这种情况下。

在我正在进行的项目中,Generic 的泛型类型比此处显示的要多,而且实现也更多,即更多 SpecificX 类。我可以通过将之前传递给SpecificX 的所有泛型类型传递给WrapperX 来避免这个问题,如下所示:

class Specific1 extends Generic<type1, type2, type3> {
  ...
}

...

class Wrapper1 extends Wrapper<type1, type2, type3> {
  ...
}

...但我只是觉得很脏,我想知道是否有更好的方法来解决这个问题。我已经定义了我的 SpecificX 类及其泛型类型,并希望避免在其他位置再次这样做。

简单的 DRY,但我不知道如何在 TypeScript 中做到这一点:(

【问题讨论】:

    标签: typescript generics dry typescript-generics


    【解决方案1】:

    如果Wrapper 应该能够包装任何Generic,并且您并不真正关心实际的Specific 类型可能是什么,那么将类型参数显式标记为unknown 会做到这一点。使用以下内容,您可以为扩展 Generic 的任何内容创建包装器。

    abstract class Wrapper<T extends Generic<unknown>>
    

    如果Wrapper 应该只包装Specific 类型之一,那么您可以使用union type 来解决问题。制作一个包含所有选项的新类型可能是个好主意。这肯定更冗长,但可以防止任何任意(例如Generic&lt;ButNotASpecificType&gt;)被包装。

    class Specific1 extends Generic<string> {
      // ...
    }
    
    class Specific2 extends Generic<number> {
      // ...
    }
    
    type Specific = Specific1 | Specific2
    
    abstract class Wrapper<T extends Specific>
    

    这是一个TypeScript playground link,展示了这两种方法。

    【讨论】:

    • 老兄,你救了我的命。 unknown 原来正是我所需要的。我确实有一些限制,但我已经使用接口对它们进行了建模。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2018-11-27
    • 2011-12-04
    相关资源
    最近更新 更多