TypeScript härleder om array[index]
Jag förväntade mig att result är number | never[]. Men faktiskt number | never[] | undefined.
type T1 = (number | undefined)[]
const myFunc = (arr: T1, index: number) => {
const result = arr[index] === undefined ? [] : arr[index]
return result // number | never[] | undefined
}
Varför beter det sig så här?
Svar #1
TypeScript använder flödesanalys för att begränsa typer av variabler. Det verkar dock inte kunna begränsa arr bara genom att kontrollera att ett av elementen är undefined:
type T1 = (number | undefined)[]
const myFunc = (arr: T1, index: number) => {
if (arr[index] === undefined) {
return []; // never[]
}
//the type of `arr` is still considered T1
let temp = arr[index]; //number | undefined
return temp;
}
Faktiskt, jag är inte säker på hur annars typen av arr bör representeras efter if-blocket (hur skulle du representera "en array av number|undefined, förutom att detta särskilda dynamiska index inte är undefined"?). Det är fortfarande lite vettigt att helt enkelt falla tillbaka till T1.
Din kod använder ternära operatorn, men den fungerar på samma sätt som min kod ovan.
Däremot kan TypeScript begränsa typerna för en result-variabel när variabeln används i en direkt jämförelse i ett flödesstyrningsuttryck:
type T1 = (number | undefined)[]
const myFunc = (arr: T1, index: number) => {
const result = arr[index];
if (result === undefined) {
return []; // never[]
}
//the type of `result` is correctly determined as number, not undefined
return result;
}
Jag tror att arr och result (variabler) kan ha sina typer begränsade av kontrollflödet, men arr[index] (ett uttryck, inte bara en variabel) kommer bara att beräknas utifrån typerna av arr och index vid det tillfället.
Svar #2
Det verkar som att TypeScript behöver lite hjälp för att härleda typer korrekt baserat på ditt ternära uttryck. Du kan åtgärda det på två sätt:
Introducera en variabel
const myFunc = (arr: T1, index: number) => {
const value = arr[index];
const result = value === undefined ? [] : value;
return result // number | never[]
}
Använd operatören för icke-null påstående för att hjälpa kompilatorn förstå att värdet aldrig kommer att vara undefined:
const myFunc = (arr: T1, index: number) => {
const result = arr[index] === undefined ? [] : arr[index]!
return result // number | never[]
}
