Búsqueda de sitios web

TypeScript type guards y "solo se refiere a un tipo, pero se está usando como un valor aquí."


Estoy usando Typescript 3.2.2 y no puedo lograr la implementación más básica de guardias de tipo:

interface Bird {
    fly(): boolean;
}

interface Fish {
    swim(): boolean;
}

function swimIfYouCan(x: Fish | Bird) {
    if ((<Fish>x).swim) {
        return true
    }
}

Esto produce Error:(50, 11) TS2693: 'Fish' solo se refiere a un tipo, pero se está usando como un valor aquí. en WebStorm y SyntaxError: /Users/sea-kent/git/docket-management/webapp/src/App.tsx: token inesperado (51:8) de yarn. ¿Se necesita alguna configuración para habilitar esta sintaxis?

Respuesta #1

Hay tres enfoques diferentes posibles que me vienen a la mente para tu problema.

  1. Si quieres convertirlo y usarlo directamente, tienes que usar el operador as (como mencionó @jonrsharpe en los comentarios), así que por ejemplo (x as Fish).swim

  2. usa el operador in para comprobar si está disponible, por ejemplo, if ('swim' in x)

  3. Por último, pero no menos importante (y en este caso, en mi opinión, el mejor caso), simplemente haz una verificación de instancia para comprobar qué instancia tienes: if (x instance of Fish)

Editar: No leí la pregunta lo suficientemente bien, no puedes comprobar las interfaces en tiempo de ejecución. Pero no hay ningún daño en crear una clase sobre la interfaz

Respuesta #2

La forma recomendada de hacer coincidencia de patrones comprobando la existencia de una propiedad es el operador in:

interface Bird {
    fly(): boolean;
}

interface Fish {
    swim(): boolean;
}

function move(x: Fish | Bird) {
  if ("swim" in x) {
    return x.swim();
  } else {
    return x.fly();
  }
}

Al usar el operador in puedes evitar la afirmación.

Artículos relacionados