¿Qué hace la palabra clave `es` en mecanografiado?


109

Encontré un código que se ve así:

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

No he podido buscar isen los documentos ni en Google, es una palabra bastante común y aparece básicamente en todas las páginas.

¿Qué hace la palabra clave en ese contexto?

Respuestas:


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

Usando el predicado de tipo "prueba es cadena" en el formato anterior (en lugar de usar booleano para el tipo de retorno, después de llamar a isString (), si la función devuelve verdadero, TypeScript reducirá el tipo a cadena en cualquier bloque protegido por un llamada a la función. El compilador pensará que foo es una cadena en el bloque protegido por debajo (y SOLO en el bloque protegido por debajo)

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

El predicado de tipo solo se usa en tiempo de compilación. El archivo .js resultante (tiempo de ejecución) no tendrá ninguna diferencia porque no considera el TIPO.

Ilustraré las diferencias en los cuatro ejemplos siguientes.

Por ejemplo, 1: el código de ejemplo anterior no tendrá errores de compilación ni de tiempo de ejecución.

Por ejemplo, 2: el código de ejemplo siguiente tendrá un error de compilación (así como un error de tiempo de ejecución) porque TypeScript ha reducido el tipo a cadena y comprobado que toExponential no pertenece al método de cadena.

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

Por ejemplo, 3: el siguiente código de ejemplo no tiene un error de compilación, pero tendrá un error de tiempo de ejecución porque TypeScript SOLO reducirá el tipo a una cadena en el bloque protegido, pero no después, por lo tanto, foo.toExponential no creará un error de compilación (TypeScript no cree que sea un tipo de cadena). Sin embargo, en tiempo de ejecución, la cadena no tiene el método toExponential, por lo que tendrá un error de tiempo de ejecución.

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

Por ejemplo, 4: si no usamos "prueba es cadena" (predicado de tipo), TypeScript no limitará el tipo en el bloque protegido y el código de ejemplo siguiente no tendrá un error de compilación pero tendrá un error de tiempo de ejecución.

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 conclusión es que "prueba es cadena" (tipo de predicado) se usa en tiempo de compilación para decirles a los desarrolladores que el código tendrá la posibilidad de tener un error en tiempo de ejecución. Para javascript, los desarrolladores NO CONOCERÁN el error en tiempo de compilación. Ésta es la ventaja de utilizar TypeScript.


11

El único uso que conozco es el de su ejemplo: especificar un "predicado de tipo" ( arg is MyType) en un tipo de protección definido por el usuario

Consulte Protectores de tipo definidos por el usuario en esta referencia.

Aquí hay otra referencia


1
También vi esto en los documentos, qué decisión de diseño más extraña, este caso se puede manejar totalmente devolviendo un tipo, boolean¿verdad?
— benjaminz

2
@benjaminz Esto podría justificar su propia pregunta sobre SO, pero puedo mostrarles un ejemplo rápido de cómo son diferentes. La ispalabra clave en realidad está lanzando el tipo y puede detectar errores de tipo más adelante en el código. Vea este ejemplo para obtener más información.
— styfle

@benjaminz No veo cómo podría ser manejado por un booleano. TypeScript necesita saber que la función en la que pasa un objeto está funcionando como un tipo de protección. Si solo devuelve el tipo verdadero o falso, ¿cómo puede Typescript saber que de hecho es un tipo de protección y no solo una función arbitraria que devuelve verdadero si el objeto es verdadero? ¿Cómo sabrá reducir el tipo de objeto? En segundo lugar, ¿cómo puede saber a qué tipo limitar el tipo de objeto? ¿Qué pasa si el parámetro es uno de los tres tipos? Necesita saber que truecorresponde a un tipo específico.
— Pushkin
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.