Tenemos una función que va a aceptar dos tipos de datos, un string y un numero y nos devolverá la longitud del string o del número
const definirLongitud=(el:string|number)=>{
return el.length
}
Intentá compilar este código. Vas a ver un error, el error es que la propiedad length solo está disponible para los strings pero no para los números, es decir que si a tu función le pasas un número, esta no va a andar. Para eso, TypeScript te pide que filtres la funcion para que trabajes con el tipo que realmente buscas. Esto comunmente se llama narrowing. La sintaxis para hacerlo es bastante sencilla
const definirLongitud=(el:string|number)=>{
if(typeof el === "string"){
return el.length
}
}
Una forma de poder hacer esto es extrayendo esa lógica en otra función. Vamos a hacerlo un poco mas complicado, supongamos que tenemos estas dos interfaces
interface Defensor{
name:string,
defender:()=>void
}
interface Delantero{
name:string,
atacar:()=>void
}
Como me aseguro de que estoy trabajando con un delantero y no con un defensor? Podria extraer la logica de narrowing en una función y luego llamarla cuando necesite hacerla. Primero voy a decirle que el tipo que puede recibir esa funcion solo puede ser un delantero o un defensor
type Jugador=Delantero | Defensor
Ahora si, ya podemos chequear a ver que tipo de jugador es para saber si atacamos o defendemos.
const esDelantero=(jugador: Jugador): jugador is Delantero=>{
return (jugador as Delantero).atacar !== undefined
}
Paso a paso, que pasó acá:
Creamos la funcion que tendra como parametro un jugador cuyo tipo será Jugador pero le decimos que trate al parametro como si fuera un delantero
En el retorno, le decimos que, al tomar a jugador como un Delantero, intente ejecutar el metodo atacar. Si el metodo atacar se ejecuta, es un delantero. Si esa ejecucion devuelve undefined, es porque no estamos trabajando con un delantero.
Ahora el resultado de esta funcion se lo podemos pasar a la funcion que nos interese para hacer el narrowing correspondiente.