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.
| Quieres | Escribe | Efecto en tiempo de ejecución |
|---|---|---|
| Decirle al compilador un tipo que conoces | x as T | ninguno |
| Convertir un string en un número | Number(x), parseInt(x, 10) | convierte |
| Convertir cualquier cosa en un string | String(x), `${x}` | convierte |
| Comprobar antes el tipo | un type guard, typeof, instanceof | comprueba |
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:
| Herramienta | Comprueba al compilar | Comprueba al ejecutar | Úsala cuando |
|---|---|---|---|
Anotación const x: T = ... | sí, por completo | no | construyes tú el valor |
satisfies T | sí, por completo, conserva el tipo inferido | no | objetos literales, configuración |
as T | solo «¿se solapan los tipos?» | no | sabes más que el compilador |
x! | solo quita null / undefined | no | sabes que un valor está asignado |
Type guard x is T | el cuerpo del guard es código normal | sí | 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.