我试图缩小枚举类型的范围,并根据枚举值返回不同的类实例。
为什么在没有使用泛型时 switch case 能够正常工作?
在示例1中,我尝试缩小扩展枚举的泛型类型的范围。然而,当我使用 switch 语句时仍会出错。
在示例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()
}
}
}
ReportFactory2
也是一个class
,那么唯一的区别就是泛型参数,会更清晰一些,像这样:https://pastebin.com/iPYXqCF7 关于实际问题,我不明白为什么 TypeScript 不允许那样做——可能与extends
有关,但是... 当然,你可以使用字面值 (case ReportType.A: { /** Works now */ return new ReportA(ReportType.A) }
),但是标签和参数之间的重复很烦人,而且(在我看来)是一个维护问题... :-| - T.J. Crowder