Hva gjør `is`-nøkkelordet i TypeScript?
Jeg kom over noe kode som ser slik ut:
export function foo(arg: string): arg is MyType {
return ...
}
Jeg har ikke klart å søke etter is verken i dokumentasjonen eller på Google, det er et ganske vanlig ord og dukker opp på nesten hver side.
Hva gjør nøkkelordet i den konteksten?
Svar #1
Se referansen for brukerdefinerte typebeskytterfunksjoner for mer informasjon.
function isString(test: any): test is string{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
}
example("hello world");
Ved å bruke typepredikatet test is string i formatet ovenfor (i stedet for bare å bruke boolean for returtypen), etter at isString() er kalt, hvis funksjonen returnerer true, vil TypeScript indusere typen til string i enhver blokk som beskyttes av et kall til funksjonen. Kompilatoren vil anta at foo er string i den nedenfor-beskyttede blokken (og BARE i den nedenfor-beskyttede blokken)
{
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
En typepredikat brukes kun under kompilering. Den resulterende .js-filen (kjøringstid) vil ikke ha noen forskjell fordi den ikke tar hensyn til TYPEN.
Jeg vil illustrere forskjellene i de fire eksemplene nedenfor.
F.eks. 1: eksempelkoden ovenfor vil verken ha en kompilasjonsfeil eller en kjøretidsfeil.
For eksempel 2: følgende eksempelcode vil få en kompilasjonsfeil (samt en kjøretidsfeil) fordi TypeScript har innsnevret typen til string og sjekket at toExponential ikke tilhører string-metoden.
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
F.eks. 3: eksempelkoden nedenfor gir ingen kompilasjonsfeil, men vil gi en kjøretidsfeil fordi TypeScript kun vil innsnevre typen til string i blokken som er beskyttet, men ikke etter, derfor vil foo.toExponential ikke skape kompilasjonsfeil (TypeScript tror ikke det er en string-type). Imidlertid finnes ikke toExponential-metoden på string ved kjøring, så det vil oppstå en kjøretidsfeil.
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
}
console.log(foo.toExponential(2));
}
F.eks. 4: hvis vi ikke bruker test is string (typepredikat), vil ikke TypeScript innsnevre typen i blokken som er beskyttet, og eksempelkoden nedenfor vil ikke ha kompileringfeil, men den vil ha en kjøretidsfeil.
function isString(test: any): boolean{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
Konklusjonen er at test is string (typepredikat) brukes i kompileringstid for å fortelle utviklerne at koden kan ha en kjøretidsfeil. For JavaScript vil ikke utviklerne VITE feilen i kompileringstiden. Dette er fordelen med å bruke TypeScript.
Svar #2
Den eneste bruken jeg kjenner til er den i eksemplet ditt: å spesifisere en "typepredikat" (arg is MyType) i en brukerdefinert Type Guard
Se Brukerdefinerte Typebeskyttere i denne referansen
Her er en annen referanse
