Vad gör nyckelordet `is` i TypeScript?
Jag stötte på lite kod som ser ut så här:
export function foo(arg: string): arg is MyType {
return ...
}
Jag har inte kunnat söka efter is varken i dokumentationen eller på Google, det är ett ganska vanligt ord och dyker upp på i princip varje sida.
Vad gör nyckelordet i det sammanhanget?
Svar #1
Se referensen för användardefinierade typvaktfunktioner för mer information.
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");
Genom att använda typpredikatet test is string i ovanstående format (istället för att bara använda boolean som returtyp), efter att isString() har anropats, om funktionen returnerar true, kommer TypeScript att begränsa typen till string i alla block som skyddas av ett anrop till funktionen. Kompilatorn kommer att anta att foo är string i det nedan-skyddade blocket (och ENDAST i det nedan-skyddade blocket)
{
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
En typ-predikat används bara under kompileringstid. Den resulterande .js-filen (körningstid) kommer inte att ha någon skillnad eftersom den inte tar hänsyn till TYPEN.
Jag kommer att illustrera skillnaderna i de fyra exemplen nedan.
T.ex 1: den ovanstående exempel koden kommer varken att ha ett kompileringsfel eller ett körtidsfel.
Till exempel 2: följande exempel kod kommer att få ett kompileringsfel (samt ett körfel) eftersom TypeScript har begränsat typen till string och kontrollerat att toExponential inte tillhör 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));
}
}
Till exempel 3: följande exempel på kod ger inget kompileringsfel men kommer att ge ett körfel eftersom TypeScript enbart kommer att begränsa typen till string inom det skyddade blocket men inte efter, därför kommer foo.toExponential inte att skapa kompileringsfel (TypeScript tror inte att det är en string-typ). Däremot har string inte metoden toExponential vid körning, så det kommer att ge ett körfel.
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
}
console.log(foo.toExponential(2));
}
T.ex. 4: om vi inte använder test is string (typ-predikat), kommer TypeScript inte att begränsa typen i den skyddade blocken och nedanstående exempel kommer inte att ge kompileringsfel men det kommer att ge ett körfel.
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));
}
}
Slutsatsen är att test is string (typ-predikat) används vid kompileringstid för att tala om för utvecklarna att koden har en chans att få ett runtime-fel. För JavaScript kommer utvecklarna inte ATT VETA felet vid kompileringstid. Detta är fördelen med att använda TypeScript.
Svar #2
Den enda användningen jag känner till är den i ditt exempel: att specificera ett "typ-predikat" (arg is MyType) i ett användardefinierat typvakt
Se användardefinierade typvakter i denna referens
Här är en annan referens
