as const en TypeScript convierte los valores y propiedades de un objeto/arreglo en readonly y tipos literales. Esto proporciona una tipificación estricta: los valores no se "expanden" al tipo base, sino que mantienen su valor específico.
Ejemplo:
const a = { status: 'success' }; // Tipo: { status: string } const b = { status: 'success' } as const; // Tipo: { readonly status: "success" }
Ventajas:
Desventajas/Características:
Pregunta: Si utilizas as const para un arreglo de cadenas, ¿cuál será su tipo y se podrá pasar como un string[] normal?
Respuesta: El tipo será readonly ["a", "b", "c"], es decir, una tupla de tipos literales con una restricción de readonly. Este arreglo no es compatible con el tipo string[]; no se puede pasar directamente a donde se espera un arreglo de cadenas mutable.
const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // ¡Error! Tipo incompatible
Historia
Proyecto: Mantenían una lista de actionTypes como un arreglo constante con as const, luego intentaron pasarlo a una función que esperaba string[]. Obtuvieron un error de tipos y tuvieron que convertirlo explícitamente con
.slice()o[...arr].
Historia
Proyecto: En un microframework de Redux, se definió el tipo action.type como un literal a través de as const. Al implementar switch-case, olvidaron la tipificación estricta y no manejaron todos los literales posibles, lo que provocó que no se activara el check exhaustivo; el error no se manifestó hasta que se agregó una nueva acción.
Historia
Proyecto: Al auto-generar endpoints de API, describieron sus claves a través de un arreglo as const. El intento de usar estas claves como índice de un Record<string, ...> falló debido a la desincronización de tipos; tuvieron que añadir una conversión, o usar explícitamente los tipos de clave del arreglo.