typescript - Type-predikater fungerer ikke i 'utvidet' filterfunksjon
Jeg har to klasser:
class Dog {
run() {
console.log("RUN")
}
}
class Fish {
swim() {
console.log("SWIM")
}
}
Jeg lager deretter en type union gjennom:
type Pet = Dog | Fish
Jeg bruker deretter en type predicate for å evaluere hva som er superklassen til Pet-instanser:
function isDog(pet: Pet): pet is Dog {
return (pet as Dog).run !== undefined
}
function isFish(pet: Pet): pet is Fish {
return (pet as Fish).swim !== undefined
}
Jeg har deretter et array av Pet-er:
const zoo: Array<Pet> = [dog, dog, dog, fish, fish, fish]
Jeg vil gjerne filtrere arrayen slik at den kun har Fish-instanser, jeg gjør:
const underwater: Array<Fish> = zoo.filter(isFish)
som fungerer.
Hvorfor fungerer ikke dette i den 'utvidede' versjonen av filter funksjonen?
const underwater2: Array<Fish> = zoo.filter((p) => isFish(p))
Svar #1
Dette er den femte saken med åpen TypeScript-issue #38390. Selv om det kan være mulig å utlede type-predicate returtyper for enkle tilfeller, ser hovedproblemet ut til å være at det ville være en brytende endring.
Akkurat nå typekontrollerer denne koden:
const pets = zoo.filter(x => isFish(x));
// const pets: Pet[]
pets.push(new Dog()); // Allowed
Men hvis en typepredikat ville blitt utledet for pilfunksjonen, ville det feilet:
const pets = zoo.filter((p): p is Fish => isFish(p));
// const pets: Fish[]
pets.push(new Dog()); // Type error
Hvis nødvendig, kan du spesifisere typepredikatet i returtypen til pilfunksjonen (dvs. (p): p er Fish => isFish(p)):
const underwater2: Array<Fish> = zoo.filter((p): p is Fish => isFish(p))
// const underwater2: Fish[]
TypeScript-lekeplass
