Menu

as en TypeScript: aserciones de tipo y casting

La palabra clave as le dice a TypeScript que trate un valor como si fuera de otro tipo. No es un cast: en tiempo de ejecución no se convierte ni se comprueba nada. Aprende la sintaxis as y la de corchetes angulares, qué permite el compilador, las aserciones dobles a través de unknown y cuándo es mejor un type guard.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

value as Type es una aserción de tipo: le dice a TypeScript que trate value como Type. La gente lo llama cast, pero es solo una instrucción para el compilador. Se borra de la salida en JavaScript, no convierte nada y no comprueba nada en tiempo de ejecución.

Este es el uso típico: sabes más sobre un valor de lo que puede saber el compilador (aquí, la forma de un JSON), y lo dices. Si te equivocas, nada te avisa. Las siguientes secciones muestran qué significa eso y cuándo es mejor una comprobación en tiempo de ejecución.

as y la sintaxis de corchetes angulares

Hay dos formas de escribir la misma aserción:

const someValue: unknown = "hello";
const a = someValue as string;   // as syntax
const b = <string>someValue;     // angle-bracket syntax, same meaning

La forma con corchetes angulares no está permitida en archivos .tsx, donde <string> se leería como una etiqueta JSX. Usa as en todas partes y la cuestión nunca aparece. Las aserciones tienen poca precedencia, así que envuélvelas en paréntesis cuando continúes la expresión: (value as string).length.

Las aserciones no convierten valores

Esta es la parte que causa bugs reales. Una aserción cambia lo que el compilador cree sobre un valor, no el valor en sí:

El compilador cree que asserted es un number, así que asserted + 1 se comprueba como aritmética. En tiempo de ejecución sigue siendo el string "42" y JavaScript concatena. Para cambiar el tipo de un valor, conviértelo: Number(x), String(x), Boolean(x), BigInt(x), new Date(x). La página de string a número compara las funciones de conversión.

QuieresEscribeEfecto en tiempo de ejecución
Decirle al compilador un tipo que conocesx as Tninguno
Convertir un string en un númeroNumber(x), parseInt(x, 10)convierte
Convertir cualquier cosa en un stringString(x), `${x}`convierte
Comprobar antes el tipoun type guard, typeof, instanceofcomprueba

Qué permite el compilador

as no es ilimitado. TypeScript permite x as T cuando uno de los tipos se puede asignar al otro: ensanchar ("a" as string, dog as Animal) y estrechar (animal as Dog, unknown as User) están permitidos. Cuando los tipos no se solapan en absoluto, lo rechaza:

El compilador informa index.ts(3,11): error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. El propio mensaje nombra la escapatoria: input as unknown as number. Esa aserción doble compila, y en tiempo de ejecución es exactamente igual de errónea que el ejemplo de arriba. Cuando sientas que la necesitas, la solución correcta suele ser una conversión (Number(input)) o un tipo distinto.

La regla del solapamiento es laxa con los objetos. Se acepta un objeto literal que tenga algunas de las propiedades, y así es como as deja pasar sin avisar objetos incompletos:

Una anotación (const draft: User = { name: "Ada" }) o satisfies User informaría de que falta email (TS2741). Usa as sobre un objeto literal solo cuando de verdad pienses completarlo más tarde, y es preferible construir el objeto completo.

as const es distinto

as const parece una aserción pero hace lo contrario de relajar: hace que un literal sea lo más estrecho posible. Los strings se quedan como tipos literales, los arrays pasan a ser tuplas readonly y las propiedades de los objetos pasan a ser readonly.

Es seguro, porque describe el literal con exactitud en lugar de afirmar algo que el compilador no puede ver. (El sizes as readonly string[] dentro de isSize es una aserción que ensancha, también segura: permite que includes acepte cualquier string). Consulta tipos literales para saber más.

Cuándo es mejor un type guard

as es una afirmación; un type guard es una comprobación. En una frontera por la que entran datos de fuera de tu código (JSON, fetch, localStorage, la entrada del usuario, un mensaje), la afirmación puede ser falsa, y una aserción convierte un error claro en la frontera en uno confuso en otro sitio.

Una guía aproximada de las herramientas que se parecen:

HerramientaComprueba al compilarComprueba al ejecutarÚsala cuando
Anotación const x: T = ...sí, por completonoconstruyes tú el valor
satisfies Tsí, por completo, conserva el tipo inferidonoobjetos literales, configuración
as Tsolo «¿se solapan los tipos?»nosabes más que el compilador
x!solo quita null / undefinednosabes que un valor está asignado
Type guard x is Tel cuerpo del guard es código normalsídatos que vienen de fuera

Quedan dos buenos usos de as: estrechar algo que el compilador no puede seguir (una entrada de un Map que asignaste dos líneas antes, un valor de una librería sin tipos), y el código de tests que construye fixtures parciales. Mantenlos pequeños y cerca del lugar donde sabes que la afirmación es cierta.

Preguntas frecuentes

¿Qué hace as en TypeScript?

value as Type es una aserción de tipo: le dice al compilador que trate value como Type a partir de ahí. Se elimina del JavaScript compilado, así que no hace ninguna conversión ni ninguna comprobación en tiempo de ejecución. Si la aserción es errónea, el programa falla más tarde, allí donde se use el tipo equivocado.

¿Cómo hago un cast de tipo en TypeScript?

TypeScript no tiene casts en tiempo de ejecución. Usa as (o la forma antigua <Type>value) para cambiar el tipo estático cuando sabes más que el compilador. Para convertir de verdad un valor, llama a una función: Number("42"), String(42), Boolean(x), new Date(text).

¿Qué significa "as unknown as" en TypeScript?

Una aserción doble. TypeScript rechaza x as T cuando los dos tipos no se solapan en absoluto (error TS2352), y pasar antes por unknown se salta esa comprobación, porque cualquier cosa se puede afirmar hacia y desde unknown. Desactiva por completo la comprobación de tipos de ese valor, así que resérvalo para tests y para código en el que hayas verificado el tipo de otra forma.

¿Qué diferencia hay entre as y los corchetes angulares en TypeScript?

Ninguna en significado: <string>value y value as string son la misma aserción. La forma con corchetes angulares no se puede usar en archivos .tsx porque choca con JSX, así que as es la forma que usa todo el mundo.

¿Qué diferencia hay entre as y satisfies?

as sustituye el tipo inferido y comprueba muy poco (se permiten propiedades que faltan). satisfies comprueba el valor contra un tipo, informando de propiedades que faltan o que sobran, y conserva el tipo inferido preciso. Prefiere satisfies para objetos literales y as solo cuando de verdad sabes más que el compilador.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR