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

Relaterte artikler