«Type 'string' is not assignable to type» — ¿qué es y por qué estás aquí?
\n\nSi alguna vez has escrito en TypeScript, seguramente te has encontrado con el subrayado rojo en el editor de código y el mensaje:
\n\nType 'string' is not assignable to type 'SomeType'.\n\nEste error es un auténtico «saludo» del tipado estricto. Asusta a los principiantes, pero en realidad es el mejor amigo del desarrollador. En este artículo analizaremos por qué surge el error Type 'string' is not assignable to type, cómo corregirlo y qué enfoques existen para trabajar con literales de cadena, tipos unión y genéricos. El artículo está escrito para el sitio educativo pythonlib.ru, pero los ejemplos son completamente en TypeScript.
\n\n1. La raíz del problema: ¿por qué TypeScript se queja de las cadenas?
\n\nTypeScript es una extensión de JavaScript que añade tipado estático. Cuando escribes:
\n\nlet role: 'admin' | 'user' = 'admin';\nrole = 'moderator'; // Error: Type '"moderator"' is not assignable to type '"admin" | "user"'\n\n\nTypeScript entiende que la variable role solo puede tomar dos valores: 'admin' o 'user'. Cuando intentas asignar 'moderator', el compilador muestra un error. Pero, ¿por qué dice «Type 'string' is not assignable to type»?
El problema es que el literal de cadena 'moderator' tiene el tipo string, mientras que el tipo esperado es 'admin' | 'user'. TypeScript compara tipos, no valores. Ve: «Me estás dando una cadena normal, pero yo espero cadenas específicas». De ahí el mensaje.
1.1. Ejemplo sencillo para entender
\n\nConsideremos un caso básico:
\n\ntype Status = 'active' | 'inactive';\n\nfunction updateStatus(status: Status) {\n console.log(status);\n}\n\nconst myStatus = 'active';\nupdateStatus(myStatus); // OK\n\nconst anotherStatus = 'pending';\nupdateStatus(anotherStatus); // Error: Type 'string' is not assignable to type 'Status'\n\n\nEn el último caso, la variable anotherStatus se infiere como string, no como 'pending'. TypeScript no sabe que 'pending' es un literal. Solo ve el tipo string. Esto se puede corregir indicando explícitamente el tipo:
const anotherStatus: 'pending' = 'pending'; // Ahora funciona\n\n\n2. Comparación de enfoques: cómo evitar o corregir el error
\n\nExisten varias formas de manejar el error Type 'string' is not assignable to type. Las compararemos en términos de simplicidad, seguridad y rendimiento.
\n\n2.1. Enfoque 1: as const — congelar el literal
\n\nLa forma más elegante es usar as const. «Congela» el valor como un literal:
const myStatus = 'active' as const;\nupdateStatus(myStatus); // OK\n\n\nVentajas: simple, legible, seguro.
\nDesventajas: solo funciona con const, no con let.
2.2. Enfoque 2: Type Assertion (as) — conversión explícita
\n\nPuedes decirle a TypeScript: «Sé lo que hago»:
\n\nconst someString: string = 'active';\nupdateStatus(someString as Status); // OK\n\n\nVentajas: solución rápida.
\nDesventajas: desactivas la verificación de tipos. Si pasas un valor incorrecto, el error solo aparecerá en tiempo de ejecución.
2.3. Enfoque 3: Type Guard (guardia de tipo)
\n\nEscribamos una función que verifique si una cadena es un estado válido:
\n\nfunction isStatus(value: string): value is Status {\n return value === 'active' || value === 'inactive';\n}\n\nfunction safeUpdate(value: string) {\n if (isStatus(value)) {\n updateStatus(value); // TypeScript sabe que value es Status\n } else {\n throw new Error('Estado no válido');\n }\n}\n