Casteos con as

Los casteos permiten engañar al sistema de tipos para que trate una variable de un tipo concreto como si fuese una variable de otro tipo. Los casteos tienen su riesgo, porque pueden provocar fallos en tiempo de ejecución, pero son beneficiosos en determinadas situaciones, por ejemplo, para forzar al sistema de tipos a ver una abstracción como si fuese un objeto de un tipo concreto.

Cuando trabajamos con TypeScript, en ocasiones nos encontramos con la necesidad de transformar variables de un tipo a otro, un proceso conocido como casteo. Esto suele ocurrir cuando manejamos jerarquías de tipos y queremos acceder a propiedades específicas que no están disponibles en la interfaz más general. Por ejemplo, imaginemos que tenemos una interfaz llamada Geometría con un campo lados de tipo number. A partir de esta, definimos otras interfaces más concretas como Triángulo, que añade propiedades como base y altura, y Cuadrado, que tiene un campo lado.

Supongamos que tenemos una función procesar que recibe un objeto de tipo Geometría para realizar operaciones generales, como pintar la figura. Sin embargo, en algún momento necesitamos acceder a propiedades específicas de un triángulo o un cuadrado. Esto implica romper la abstracción que nos ofrece la interfaz general, ya que estamos entrando en detalles concretos que la interfaz Geometría oculta a propósito para simplificar el manejo de diferentes formas.

Un caso práctico que ilustra esta necesidad es el uso de la librería Discord.js, donde existen distintos tipos de mensajes: mensajes privados a una persona, mensajes privados a un grupo, mensajes públicos en un servidor, todos bajo una interfaz común llamada Message. Para acceder a propiedades específicas de cada tipo de mensaje, es necesario realizar casteos que nos permitan tratar el objeto como su tipo más concreto.

En nuestro ejemplo geométrico, podríamos comprobar si g.lados es igual a 4 para inferir que g es un cuadrado. Entonces, podemos hacer un casteo para tratar g como un objeto de tipo Cuadrado y acceder a su propiedad lado. De forma similar, si g.lados es 3, podemos castear g a Triángulo y acceder a base o altura.

Para realizar estos casteos en TypeScript, la forma recomendada es usar la palabra clave as, que nos permite indicar el tipo al que queremos transformar la variable. Por ejemplo:

interface Geometría {
  lados: number;
}

interface Triángulo extends Geometría {
  base: number;
  altura: number;
}

interface Cuadrado extends Geometría {
  lado: number;
}

function procesar(g: Geometría) {
  if (g.lados === 4) {
    const cuadrado = g as Cuadrado;
    console.log(cuadrado.lado);
  } else if (g.lados === 3) {
    const triángulo = g as Triángulo;
    console.log(triángulo.base, triángulo.altura);
  }
}

Existe otra sintaxis para hacer casteos que consiste en poner el tipo entre los símbolos < y > antes de la variable, como si fuera una etiqueta HTML:

const cuadrado = <Cuadrado>g;

Sin embargo, esta forma tiene limitaciones importantes. En proyectos que usan React con JSX o TSX, esta sintaxis puede confundirse con elementos JSX, lo que provoca errores y confusiones en el compilador. Por esta razón, es preferible evitar esta forma y usar siempre la palabra clave as para hacer casteos, especialmente en entornos donde se utiliza React.

Además, aunque se intente desactivar el modo React en la configuración, puede que el compilador siga interpretando esta sintaxis como JSX, lo que refuerza la recomendación de usar as. Muchos linters y herramientas de análisis de código también fomentan esta práctica para evitar problemas.

Por último, es importante mencionar que los casteos no son la única forma de trabajar con tipos en TypeScript. También existen mecanismos para hacer comprobaciones de tipo (checks) que nos permiten verificar si un objeto es de un tipo concreto antes de realizar operaciones específicas. Estos checks son una herramienta complementaria que veremos en detalle en otro momento.

Lista de reproducción
  1. 1
    Temporada 1
    5 minutos
  2. 2
    ¿Qué es TypeScript?
    11 minutos
  3. 3
    Instalando TypeScript
    8 minutos
  4. 4
    Compilando un Hola Mundo sencillo
    7 minutos
  5. 5
    Hola Mundo pero con tipos
    10 minutos
  6. 6
    Tipos: tipos primitivos
    12 minutos
  7. 7
    Tipos: tipos especiales (any, null, ...)
    10 minutos
  8. 8
    Tipos: arrays y tuplas
    11 minutos
  9. 9
    Tipos: objetos
    7 minutos
  10. 10
    Funciones: lo básico
    9 minutos
  11. 11
    Funciones: tipando funciones
    9 minutos
  12. 12
    Clases: introducción a las clases
    9 minutos
  13. 13
    Clases: creando una clase
    10 minutos
  14. 14
    Clases: modificador private
    8 minutos
  15. 15
    Clases: modificador readonly
    3 minutos
  16. 16
    Clases: Atributos virtuales con getters y setters
    10 minutos
  17. 17
    Clases: herencia
    9 minutos
  18. 18
    Clases: modificadores abstract y protected
    8 minutos
  19. 19
    Tipos alias
    6 minutos
  20. 20
    Tipos literales
    5 minutos
  21. 21
    Uniones de tipos
    7 minutos
  22. 22
    Uniones discriminantes
    7 minutos
  23. 23
    Intersecciones de tipos
    5 minutos
  24. 24
    Interfaces: introducción
    7 minutos
  25. 25
    Interfaces: modificadores y funciones
    9 minutos
  26. 26
    Interfaces: usándolas con clases
    8 minutos
  27. 27
    Interfaces: herencia de interfaces
    8 minutos
  28. 28
    Interfaces: interfaces indizadas
    5 minutos
  29. 29
    Interfaces: funciones y tipos híbridos
    5 minutos
  30. 30
    ¿Qué diferencia hay entre interfaces y tipos? (2020)
    8 minutos
  31. 31
    Casteos con as
    6 minutos
  32. 32
    instanceof y las guardas
    9 minutos
  33. 33
    Tipos enumerados
    8 minutos
  34. 34
    Valores avanzados para enumerados
    7 minutos
  35. 35
    Enumerados con valores computados
    6 minutos
  36. 36
    Genéricos en tipos
    8 minutos
  37. 37
    Múltiples genéricos y buenas prácticas
    5 minutos
  38. 38
    Genéricos en funciones
    8 minutos
  39. 39
    Genéricos con restricciones
    6 minutos
  40. 40
    Tipos de utilidad
    3 minutos
  41. 41
    Exportando módulos
    9 minutos
  42. 42
    Importando módulos
    7 minutos
  43. 43
    Export default e import asterisco
    6 minutos
  44. 44
    tsconfig
    7 minutos
  45. 45
    Módulos desde NPM
    7 minutos
  46. 46
    Arroba types y los .d.ts
    8 minutos
  47. 47
    Ejemplo (1): creando una API REST simple en TypeScript
    11 minutos
  48. 48
    Ejemplo (2): montando un servidor Express
    8 minutos
  49. 49
    Ejemplo (3): haciendo las funciones de control de datos
    11 minutos
  50. 50
    Ejemplo (4): conectando todas las piezas
    7 minutos