typescript - Innsnevring av typer ved bruk av switch-setning fungerer ikke på en generisk type


Jeg prøver å begrense en enum-verdi og returnere en annen instans av en klasse avhengig av enum-verdien.

Hvorfor fungerer switch-case når man ikke bruker generics?

I eksempel 1 prøver jeg å avgrense en generisk type som utvider en enum. Men det gir fortsatt feil når jeg bruker switch-setninger.

I eksempel 2 forårsaker det ikke en feil å innsnevre en enum-type direkte.

Finnes det noen begrunnelse for dette?

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()
      }
   }
}


Lekeplass her

Svar #1

Dette ser ut som et problem fra TypeScript. Takk til @Yury Tarabanko for å lenke.

Tilsynelatende er den eneste løsningen for meg å caste typen eller bruke // @ts-ignore-kommentaren.

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