262 votes

Que fait le mot clé "is" dans le langage courant ?

Je suis tombé sur un code qui ressemble à ceci :

export function foo(arg: string): arg is MyType {
    return ...
}

Je n'ai pas été capable de chercher is dans les docs ou dans google, c'est un mot assez commun qui apparaît sur presque toutes les pages.

Que fait le mot-clé dans ce contexte ?

0 votes

J'ai trouvé ce tutoriel utile : youtu.be/eJ6R1knfsoc?t=300 Regardez de 5h00 à 6h50

308voto

ARIES CHUI Points 384

Voir la référence pour fonctions de protection de type définies par l'utilisateur pour plus d'informations.

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");

Utilisation du prédicat de type test is string dans le format ci-dessus (au lieu d'utiliser simplement boolean pour le type de retour), après isString() est appelé, si la fonction renvoie true , TypeScript réduira le type à string dans tout bloc gardé par un appel à la fonction. Le compilateur pensera que foo est string dans le bloc sous-gardé (et UNIQUEMENT dans le bloc sous-gardé)

{
    console.log("it is a string" + foo);
    console.log(foo.length); // string function
}

Un prédicat de type n'est utilisé qu'au moment de la compilation. Le résultat .js (runtime) ne fera aucune différence car il ne prend pas en compte le TYPE.

Je vais illustrer les différences dans les quatre exemples ci-dessous.

E.g 1 : l'exemple de code ci-dessus n'aura pas d'erreur de compilation ni d'erreur d'exécution.

E.g 2 : l'exemple de code ci-dessous aura une erreur de compilation (ainsi qu'une erreur d'exécution) parce que TypeScript a réduit le type à string et vérifié que toExponential n'appartient pas à string méthode.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Par exemple, 3 : l'exemple de code ci-dessous n'a pas d'erreur de compilation mais aura une erreur d'exécution parce que TypeScript va SEULEMENT restreindre le type à string dans le bloc gardé mais pas après, donc foo.toExponential ne créera pas d'erreur de compilation (TypeScript ne pense pas que c'est une string type). Cependant, en cours d'exécution, string n'a pas le toExponential ce qui entraînera une erreur d'exécution.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
    }
    console.log(foo.toExponential(2));
}

Par exemple, 4 : si on n'utilise pas test is string (prédicat de type), TypeScript ne restreindra pas le type dans le bloc gardé et le code de l'exemple ci-dessous n'aura pas d'erreur de compilation mais il aura une erreur d'exécution.

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));
    }
}

La conclusion est que test is string (prédicat de type) est utilisé à la compilation pour indiquer aux développeurs que le code aura une chance d'avoir une erreur à l'exécution. Pour le javascript, les développeurs ne sauront pas l'erreur au moment de la compilation. C'est l'avantage d'utiliser TypeScript.

17voto

BGR Points 4330

La seule utilisation que je connaisse est celle de votre exemple : spécifier un " prédicat de type " ( arg is MyType ) dans un Type Guard défini par l'utilisateur

Voir les protections de type définies par l'utilisateur dans ce référence

En voici un autre référence

2 votes

J'ai vu cela dans la documentation aussi, quelle décision de conception bizarre, ce cas peut tout à fait être géré en retournant un type boolean n'est-ce pas ?

2 votes

@benjaminz Cela pourrait justifier une question à part entière sur SO mais je peux vous montrer un exemple rapide de leur différence. Le site is est en fait un casting du type et peut permettre de détecter des erreurs de type plus tard dans le code. Voir cet exemple pour plus d'informations.

2 votes

@benjaminz Je ne vois pas comment cela pourrait être géré par un booléen. Typescript doit savoir que la fonction dans laquelle vous passez un objet fonctionne comme une garde de type. Si elle renvoie simplement le type true ou false, comment Typescript peut-il savoir qu'il s'agit bien d'un garde de type et non d'une fonction arbitraire qui renvoie true si l'objet est truthy. Comment saura-t-il qu'il faut restreindre le type de l'objet ? Deuxièmement, comment peut-il savoir à quel type réduire le type de l'objet ? Et si le paramètre est l'un des trois types suivants ? Il doit savoir que true correspond à un type spécifique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X