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 TestInputmedinterface BaseInputProps<string>, vil det forsøge at tjekke, om alle egenskabstyperne er kompatible, men i dette tilfælde er typencustomRef?: (selfProps: this) => void;af typen(selfProps: this)=> voidikke tildelbar tilstringog omvendt. Derfor er det falsk arv, hvilket gør, at S1 ernever.
Sag 2: Når du fjerner label og customRef, er det streng
Når du fjerner label og customRef, vil
interface BaseInputPropsoginterface TestInputblive udeladt med én obligatorisk egenskabvalue, 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 BaseInputPropsoginterface TestInputvil 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.