El paso de programar en Javascript a programar en Typescript, aunque puede implementarse gradualmente, añade algo de complejidad y tiempo de aprendizaje. Sin embargo, sus ventajas son tan relevantes que vale la pena transitar ese proceso. Somos muchos los que, una vez probado Typescript, no queremos volver atrás.

Typescript es un lenguaje que añade sintaxis a JavaScript para permitir, entre otras cosas, la definición de tipos. Fue desarrollado por Microsoft y publicado en 2012. Desde entonces ha estado en permanente actualización y actualmente se encuentra en la versión 4.4.

El código Typescript no es comprensible para los navegadores o Node.js, por esa razón es necesario transpilarlo con Babel o el tsc (Typescript Compiler), por ejemplo. A su vez, creando un archivo tsconfig.json, podrás determinar las opciones que quieras para esa transpilación, como por ejemplo, el estándar ECMAScript. Como veremos, durante este proceso de transpilación aparecen errores que de otra manera podrían pasar desapercibidos y llegar a producción.

Migrar de JavaScript a Typescript es muy fácil puesto que todo código JavaScript es código Typescript válido. Es decir, Typescript añade características al lenguaje JavaScript que pueden implementarse de forma gradual pudiendo hacer cambios mínimos en el código para empezar a beneficiarse de éstas. Estas características aportan ventajas no sólo para desarrollar aplicaciones más robustas, sino para mejorar la experiencia de desarrollo del programador. En este artículo nos proponemos enumerar algunas de esas ventajas para animarte a dar el paso de utilizar Typescript en tus proyectos.

Facilidades en el momento de programar

El editor de código es de mucha ayuda al momento de programar con Typescript. Si el editor soporta Typescript será capaz de informarte de errores en el código al momento de escribirlo, con lo que te ahorrará mucho tiempo y seguramente algún que otro bug. El editor Visual Studio Code, por ejemplo, está escrito en Typescript, por lo que ya puedes imaginarte lo bien que se integra ese editor con este lenguaje de programación, para ofrecer una excelente experiencia al desarrollador.

Si intentas invocar un método que no se corresponde con el tipo de dato sobre el cual lo quieres aplicar — utilizar find() en un dato de tipo Object — o si intentas cambiar el tipo de dato para una variable con su tipado ya definido — asignar un number a una variable de tipo string —. En ambos casos el editor te notificará el error al instante.

Una de las primeras ventajas que vamos a notar al programar con Typescript es la asistencia IntelliSense que te ayudará a programar más rápido y con menos errores.

Veamos un ejemplo:

En primer lugar vamos a definir una interface. Una interface es una estructura que actúa como un contrato. En este caso, la interface nos permitirá definir la estructura de un objeto “Article” con sus propiedades y sus tipos respectivos:

interface Color {
  id: number,
  code: number,
  name: string
}
interface Article {
  articleName: string,
  articleDescription: string,
  colorsList: Array<Color>,
  idArticle: number,
  price: number,
 }

En el ejemplo definimos 5 propiedades para Article: dos de tipo string (articleName y articleDescription), dos de tipo number (idArticle y price), y una de tipo Array (colorsList), que a su vez tiene una interface definida para cada elemento del array (Color), la cual hemos definido previamente.

En el momento de programar podría ser difícil recordar las propiedades de Article o, más aún, las de cada elemento de colorsList. Es aquí donde intelliSense, gracias a Typescript, nos ayuda:

Una oda a Typescript

Como ves en la imagen, estamos recorriendo el array de colorsList y al intentar acceder a una de las propiedades de cada elemento (colorItem), basta con poner el punto para que el editor nos sugiera las propiedades del propio elemento (code, id, name). De esta manera no tenemos que recordarlas o arriesgarnos a escribirlas mal.

Prevenir bugs en producción

Como hemos dicho antes, Typescript nos ayuda a evitar bugs en producción al detectar en el momento de la transpilación errores que de otra manera podrían ocurrir con la aplicación ya desplegada. Para mostrar un ejemplo vamos a utilizar un componente React. En este componente definimos las propiedades que espera recibir, identificando cuáles son obligatorias y cuáles opcionales:

type Props = {
  title?: string,
  onClose: Function,
  open: boolean
}

const ModalComponent: React.FC<Props> = ({ title, onClose, open }: Props ): JSX.Element => (
  <Modal
    visible={open}
    onClose={() => onClose()}
  >
    {title}
  </Modal>
);

Lo primero que hemos definido es la API del componente ModalComponent. Hemos determinado que este componente espera recibir una propiedad title de tipo string, otra onClose de tipo Function y otra más, llamada open, de tipo boolean. Como verás title tiene un signo de interrogación y esto significa que es una propiedad opcional, a diferencia de las otras dos. Ahora vamos a intentar crear una instancia del componente:

 <ModalComponent
    title="title test"
    onClose={() => onCloseFunction()}
   />

En la instancia hemos olvidado pasar la propiedad open al componente. El editor nos advierte de esto subrayando en rojo el componente, y si nos posicionamos encima nos dirá que falta la propiedad open. Pero si no vemos esta advertencia, al transpilar el código nos mostrará el error y podremos ver y corregir este fallo.

Hacer el código más legible y documentado

Typescript se vuelve mucho más útil cuanto más grande es el proyecto o más desarrolladores trabajan en él. Una de las razones es que la propia sintaxis facilita la legibilidad y funciona como documentación para que el código escrito por un desarrollador sea mucho más claro para el resto de desarrolladores y, por lo tanto, más fácil de reutilizar.

Un ejemplo de ello son las funciones:

function formatPrice(price: number): string {
  return new Intl.NumberFormat('es-ES', 
            { style: 'currency', currency: 'EUR' }).format(price)
      }

Veamos la primera línea del ejemplo. Declaramos una función (formatPrice) y establecemos que va a recibir un parámetro (price). Aquí ya estamos también definiendo que ese parámetro será de tipo number (price: number). Además, estamos definiendo el tipo de valor que retorna la función, al añadir :string antes de las llaves. Por lo tanto, para alguien que quiera reutilizar esta función, queda mucho más claro qué tipo de dato debe pasar como parámetro y qué tipo de dato va a recibir una vez retornado el valor de la función.

Definir conjuntos de datos válidos para evitar valores incorrectos

Hay varias utilidades de Typescript para acotar un conjunto de datos válidos. Una de ellas son las const assertions. Con esta utilidad podemos definir, por ejemplo, un objeto cuyas propiedades pasan a ser de solo lectura (readonly). Vamos a utilizarla (as const) para definir un conjunto de datos llamados AvailableGenres:

const availableGenres = {
  ADV: 'adventure',
  BIO: 'biography',
  SFI: 'scienceFiction',
  FAN: 'fantasy',
  HFI: 'historicalFiction',
  POL: 'policial',
  ROM: 'romantic',
  SUS: 'suspense',
  TER: 'terror',
  THR: 'thriller',
} as const;

Luego podemos definir un type llamado Genre, donde vamos a establecer que el name solo puede ser uno de los valores de AvailableGenres y el code solo puede ser una de las claves de AvailableGenres.

type Genre = {
  name: typeof availableGenres [keyof typeof availableGenres],
  code: keyof typeof availableGenres
}

Finalmente, le asignamos a un bookGenre, sus valores de name y code válidos:

const bookGenre: Genre = {
  name: 'adventure',
  code: 'ADV'
}

Si, por ejemplo, asignásemos erróneamente como name el valor ‘adventures’, nos señalaría un error:

Una oda a Typescript

Otra utilidad interesante para acotar datos son los Enums. Con ellos podemos definir un conjunto de datos de manera de documentar cuales son los permitidos o válidos:

enum AvailableGenres {
  ADV = 'adventure',
  BIO = 'biography',
  SFI = 'scienceFiction',
  FAN = 'fantasy',
  HFI = 'historicalFiction',
  POL = 'policial',
  ROM = 'romantic',
  SUS = 'suspense',
  TER = 'terror',
  THR = 'thriller',
};

const bookGenre: AvailableGenres = AvailableGenres.ADV;

En el ejemplo, hemos definido los géneros literarios posibles utilizando un enum. Luego, cuando vamos a asignar a la variable bookGenre, del tipo AvailableGenres, su valor, debemos elegir un valor del enum. Aquí también basta con escribir el nombre del enum y el punto para que Typescript nos sugiera una opción válida y así poder prevenir errores.

Conclusión

Las posibilidades de Typescript para hacer nuestro código más robusto son muchas y, a su vez, la flexibilidad para aplicarlas es máxima. Por esta razón, el desafío es saber utilizar esta sintaxis adicional de JavaScript a nuestro favor, allá donde el código es susceptible de errores, para prevenirlos y para facilitar a otros desarrolladores la legibilidad, la reusabilidad y el mantenimiento del mismo.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.