typescript - Generiska typvakter som antar never
Den här koden:
class X<T> {
isString(): this is X<string> {
return true;
}
isNumber(): this is X<number> {
return false;
}
}
const x = new X();
if (x.isString()) {
} else if (x.isNumber()) { // Line 15
}
Vilket jag tycker semantiskt är korrekt, genererar detta fel:
meddelande: 'Egenskapen 'isNumber' finns inte på typen 'never'.' vid: '15,14'
Varför? Hur ska jag skriva if-batchen av meningar?
Svar #1
Typer i TypeScript är strukturella.
I ditt exempel är X<string> och X<number> strukturellt identiska - de har båda två typvaktmetoder, isString() och isNumber(), och inget annat. Så kompilatorn antar att om den första typvakten returnerar sant, måste den andra också returnera sant (eftersom de i verkligheten testar för samma typ), och else-grenen är oåtkomlig.
Så snart du får X att faktiskt bero på T, kompilerar det:
class X<T> {
t: T;
isString(): this is X<string> {
return true;
}
isNumber(): this is X<number> {
return false;
}
}
const x = new X();
if (x.isString()) {
} else if (x.isNumber()) { // Line 15
}
