【问题标题】:Narrowing types using switch statement does not work on a generic type使用 switch 语句缩小类型不适用于泛型类型
【发布时间】:2020-11-25 07:47:55
【问题描述】:

我正在尝试缩小枚举值并根据枚举值返回一个不同的类实例。

为什么不使用泛型时 switch case 可以工作?

在示例 1 中,我试图缩小扩展枚举的泛型类型。但是,当我使用 switch case 时,它​​仍然会出错。

在示例 2 中,直接缩小枚举类型不会导致错误。

这背后有什么原因吗?

class ReportA {
   constructor(public type: ReportType.A) { }
}

class ReportB {
   constructor(public type: ReportType.B) { }
}

enum ReportType {
   A = "A",
   B = "B"
}

/** Example 1. Does not work... Why? */
class ReportFactory<Type extends ReportType> {
   constructor(public type: Type) { }

   public create = () => {
      switch (this.type) {
         case ReportType.A: {
            /** ERROR! */
            return new ReportA(this.type)
         }
         case ReportType.B: {
            /** ERROR! */
            return new ReportB(this.type)
         }
         default: throw new Error()
      }
   }
}

/** Example 2. Works */
class ReportFactory2 {
   constructor(public type: ReportType) { }
 
   public create = () => {
      switch (this.type) {
         case ReportType.A: {
            /** WORKS! */
            return new ReportA(this.type)
         }
         case ReportType.B: {
            /** WORKS! */
            return new ReportB(this.type)
         }
         default: throw new Error()
      }
   }
}


Playground here

【问题讨论】:

  • FWIW,如果 ReportFactory2 也是 class 会更清楚,所以 only 区别是通用参数,如下所示:pastebin.com/iPYXqCF7 实际问题,不过,我不明白为什么 TypeScript 不允许这样做 - 可能与 extends 但...您当然可以只使用文字值(case ReportType.A: { /** Works now */ return new ReportA(ReportType.A) } ),但案例之间的重复标签和论点令人恼火,并且(在我看来)是维护问题...:-|
  • @T.J.Crowder 感谢您的建议。我已经用它编辑了我的示例。

标签: typescript


【解决方案1】:

这看起来像是来自 TypeScript 的 issue。感谢@Yury Tarabanko 提供链接。

似乎对我来说唯一的解决方案是强制转换类型或使用// @ts-ignore 评论。

new ReportA(this.type as ReportType.A)
// @ts-ignore
new ReportA(this.type)

【讨论】:

猜你喜欢
  • 2022-08-17
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 2023-02-11
  • 1970-01-01
相关资源
最近更新 更多