Fundamentos de TypeScript 馃| #9: Narrowing

Cristian Fernando - Jan 19 '22 - - Dev Community

Es una t茅cnica que se usa sobre todo en los par谩metros de una funci贸n. Consiste en que por medio de validaciones podamos modificar el flujo de la funci贸n dependiendo si sus par谩metros aceptan varios tipos de datos a la vez mediante uniones de tipos.

La forma m谩s com煤n de Narrowing se observa usando el operador typeof y condicionales, de este manera podemos controlar c贸mo actuar谩 esa funci贸n de manera controlada y evitando bugs.

Veamos algunos ejemplos para comprender todo esto.

//creamos una tupla de strings
const choices: [string, string] = ['NO', 'YES'];

const processAnswer = (answer: number | boolean) => {
  if (typeof answer === 'number') {
    console.log(choices[answer]);
  } else if (typeof answer === 'boolean') {
    if (answer) {
      console.log(choices[1]);
    } else {
      console.log(choices[0]);
    }
  }
}
processAnswer(0);       // Prints "NO"
processAnswer(true);    // Prints "YES"
Enter fullscreen mode Exit fullscreen mode

Analicemos la funci贸n processAnswer, s贸lo recibe un par谩metro answer que puede ser number o boolean.

  • Si answer es number:
    Accedemos a la tupla choices en la posici贸n que le pasemos, siendo choices[0] = 'NO' y choices[1] = 'SI'; ergo, si llamamos a la funci贸n processAnswer(0) obtendremos como salida NO.

  • Si answer es boolean:
    Si answer existe entonces regresamos choices[1], osea SI.
    Si answer no existe entonces regresamos choices[0] osea NO.

驴Bastante f谩cil verdad?

Veamos otro ejemplo:

function roughAge(age: number | string) {
  if (typeof age === 'number') {
    // In this block, age is known to be a number
    console.log(Math.floor(age));
  } else {
    // In this block, age is known to be a string
    console.log(age.split(".")[0]);
  }
}
roughAge('3.5');  // Prints "3"
roughAge(3.5);    // Prints 3
Enter fullscreen mode Exit fullscreen mode

La funci贸n roughAge recibe un solo par谩metro age, nuevamente evaluamos que har谩:

  • Si age es number redondeamos el valor hacia abajo con Math.floor(), por ello llamar roughAge(3.5) regresa el n煤mero 3.

  • Si age es string usamos el m茅todo split de las cadenas y obtenemos la primera posici贸n de dicha cadena. Por ello si llamamos roughAge('3.5') obtenemos '3' como string.

Conclusiones

  • Narrowing es un t茅cnica muy poderosa y sencilla de comprender para que el flujo de las funciones hagan lo que nosotros necesitamos.
  • Usualmente typeof ser谩 nuestro mejor aliado al momento de hacer Narrowing.

Referencias

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .