ProgramaciónDesarrollador Frontend

¿Cómo funciona el mecanismo de tipos de literales de plantilla (Template Literal Types) en TypeScript y para qué sirve?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Historia del tema

TypeScript durante mucho tiempo permitió describir tipos literales para valores de cadena o numéricos individuales, sin embargo, con la aparición de los literales de plantilla surgió la necesidad de tipificar patrones de cadena específicos. Los Template Literal Types añaden la capacidad de describir tipos basados en la concatenación de cadenas de plantilla, lo que proporciona una validación estática de la estructura de los valores de cadena.

Problema

Comprobar la conformidad de una cadena a un formato específico (por ejemplo, 'user_42') con los tipos string convencionales es imposible — son demasiado generales. Sin tipos de plantilla, el compilador no puede garantizar que la cadena se ajuste a un patrón estricto.

Solución

Los Template Literal Types permiten formar tipos de cadena complejos en el momento de la compilación y garantizan una verificación estricta de su conformidad con ciertos patrones.

Ejemplo de código:

type UserId = `user_${number}`; function loadUser(id: UserId) { // ... } loadUser('user_123'); // correcto loadUser('admin_123'); // error de compilación

Características clave:

  • Formación de tipos de cadena basados en uniones literales
  • Soporte para combinaciones, anidamientos y manipulaciones con claves de objetos
  • Aumento de la seguridad de tipo para identificadores de cadena, URL y otras estructuras

Preguntas engañosas.

¿Se pueden usar Template Literal Types solo con number/literal? ¿Se pueden usar literales de cadena propios en la plantilla?

Se pueden usar cualquier tipo literal — cadenas, números, uniones:

type EventType = `event_${'click' | 'hover'}`; // event_click | event_hover

¿Se puede pasar una cadena normal si la función espera un tipo Template Literal?

No, si el tipo espera explícitamente un literales de plantilla, simplemente string no es adecuado:

function handler(type: `btn_${string}`) {} handler('btn_click'); // ok handler('button'); // error de compilación

¿Funcionan los tipos de cadena de plantilla con tipos mapeados y keyof?

Sí, los Template Literal Types se combinan muy bien con los tipos mapeados y las claves de los objetos:

const colors = {red: 1, blue: 2}; type ColorKey = keyof typeof colors; type ColorClass = `color-${ColorKey}`; // color-red | color-blue

Errores comunes y anti-patrones

  • Uso de tipo de plantilla donde se adapta cualquier string
  • Tipos de plantilla demasiado agresivos que no dejan flexibilidad
  • Vinculación de tipos a valores de runtime que no son controlados por el compilador

Ejemplo de la vida real

Caso negativo

La API acepta identificadores del tipo 'user_XXX', la función no está tipificada — se puede enviar cualquier cadena, se producen errores en el servidor.

Ventajas:

  • No hay restricciones en el valor

Desventajas:

  • El equipo comete errores al enviar cadenas incorrectas; las pruebas son superficiales

Caso positivo

Se utiliza el tipo UserId = user_${number}, garantizando en el momento de la compilación la corrección de los argumentos de las funciones y consultas seguras al servidor.

Ventajas:

  • Reducción del número de errores, validación de tipos estricta
  • Mejora de la autocompletación y legibilidad del código

Desventajas:

  • Requiere actualización de los tipos de plantilla al cambiar el esquema de datos