ProgramaciónDesarrollador Frontend

¿Cómo funciona la tipificación de objetos constantes con la propiedad as const? ¿Cuáles son las ventajas y problemas que pueden surgir con una tipificación incorrecta de tales objetos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

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:

  • Tipificación estricta (por ejemplo, switch/case en cadenas, listas de constantes)
  • Ideal para enums, actionTypes en Redux, listas de roles, etc.
  • Previenes modificaciones accidentales de valores

Desventajas/Características:

  • Las propiedades se vuelven readonly, intentar modificarlas provocará un error.
  • Un uso descuidado puede llevar a incompatibilidades de tipos (por ejemplo, si se necesita una cadena y se pasó un literal).

Pregunta capciosa

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

Ejemplos de errores reales debido al desconocimiento de los matices del tema


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.