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.