Hvorfor fejler TypeScripts typeinferens i dette tilfælde?


Jeg vil forstå, hvorfor typen S1 er never, men når jeg fjerner label eller customRef-egenskaberne får jeg korrekt resultat af string. Når jeg fjerner value og label-egenskaberne får jeg unknown.

export interface BaseInputProps<TStored> {
  value: TStored;
  customRef?: (selfProps: this) => void;
}

export interface TestInput extends BaseInputProps<string> {
  label: string;
}

type InferStoredType<T> = T extends BaseInputProps<infer TT> ? TT : never;

type S1 = InferStoredType<TestInput>;

Hvad sker der her?

Typescript version 3.7.5. Fungerer på samme måde på Typescript-legeredet.

Svar #1

Det har at gøre med den strukturelle forskel og svag type. Så lad os forstå dit problem i alle tilfælde

Sag 1: Som standard er det aldrig

Når du forsøger at udvide interface TestInput med interface BaseInputProps<string>, vil det forsøge at tjekke, om alle egenskabstyperne er kompatible, men i dette tilfælde er typen customRef?: (selfProps: this) => void; af typen (selfProps: this)=> void ikke tildelbar til string og omvendt. Derfor er det falsk arv, hvilket gør, at S1 er never.

Sag 2: Når du fjerner label og customRef, er det streng

Når du fjerner label og customRef, vil interface BaseInputProps og interface TestInput blive udeladt med én obligatorisk egenskab value, hvilket gør, at det korrekt kan inferere typingen.

Sag 3: Når du fjerner værdi og mærkat, er det ukendt

Når du fjerner værdien og etiketten interface BaseInputProps og interface TestInput vil blive udeladt med kun en valgfri egenskab, og TypeScript kan ikke garantere typningerne i dette tilfælde.

Alligevel er spørgsmålet, hvorfor denne ændring var tilsigtet. Men når man ser på omfanget af ændringen i specifikationen, vil jeg gætte på, at det er meget svært at se en ændring i dette.

Læs venligst også dette for mere om svag typning og om betingede typninger.

Relaterede artikler