javascript - Fungerar inte typeof typeguard när det tilldelas en variabel?
Jag får ett fel när jag använder en typeof som nedan.
function func (variable: number | string) {
const is_number = (typeof variable === 'number');
let variable2: number,
variable3: string;
if (is_number)
variable2 = variable;
=> Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
else
variable3 = variable;
=> Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
}
Det finns dock inget fel som nedan.
function func (variable: number | string) {
let variable2: number,
variable3: string;
if (typeof variable === 'number')
variable2 = variable;
else
variable3 = variable;
}
URL för test
Måste jag alltid använda det som ovan? Eller finns det någon del som jag har använt fel?
Tack för att du läste :)
Svar #1
@Ry- har redan svarat på den faktiska frågan i kommentarerna. Nedan är en lösning för begränsningen.
Det ÄR möjligt att göra något liknande det du försöker uppnå med en hjälpfunktion som jag kommer att kalla isNumber, som bekräftar om ett givet argument extends en viss typ i TypeScript. Detta ger ett sätt att inte inlinea en JS-typkontroll som typeof variable === "number" trots allt. Istället är kontrollen nu innesluten i en funktion.
Detta görs med x is y-konstruktionen, som kallas en typprädikat (du får scrolla ner lite). I följande kodsnutt är returtypen för isNumber ett sådant typprädikat:
const isNumber = (subject: any): subject is number => {
return typeof subject === 'number';
};
Här kan TypeScript härleda typen number från boolean som returneras från isNumber. Nu, om du använder denna hjälpfunktion i din egen func, bör allt vara bra:
function func (variable: number | string) {
let variable2: number;
let variable3: string;
if (isNumber(variable)) {
variable2 = variable;
} else {
variable3 = variable;
}
}
Eftersom if-blocket endast någonsin kommer att köras om isNumber(variable) returnerar true, kommer Typescript nu att anta att subject är number. Följande pseudokod visar hur ovanstående kod bör tolkas av TS:
if (variable is number) {
// ...
}
Jag hittade också detta SO-svar som förklarar typ-predikatkonstruktionen ytterligare.
