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.
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).swimusa el operador
inpara comprobar si está disponible, por ejemplo,if ('swim' in x)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.
