Template Literal Types en TypeScript

Una de las funcionalidades más curiosas que incluye TypeScript son los Template Literal Types. Básicamente es una forma de crear tipos usando texto dinámico, combinando strings fijos con otros textos. Funcionan como los template strings de JavaScript, pero con tipos.

Veamos un ejemplo para que quede más claro:

type LogLevel = 'INFO' | 'WARN' | 'ERROR';

type FileLogLevel = `FILE_${LogLevel}`;
// Esto genera este tipo 👇
// type FileLogLevel = "FILE_INFO" | "FILE_WARN" | "FILE_ERROR"

Vamos desglosando el ejemplo anterior:

  1. Definimos un union type de tres strings llamado LogLevel.
  2. Definimos un nuevo tipo llamado FileLogLevel, es cual es definido como un template literal y este nuevo tipo ahora es una unión del string que tenemos FILE_ con cada uno de los valores de nuestra unión LogLevel.

Además, podemos combinar diferentes union types para crear todas las combinaciones posibles entre estos tipos:

type DatabaseType = 'MySQL' | 'PostgreSQL' | 'SQLite';
type LogLevel = 'INFO' | 'WARN' | 'ERROR';

type DatabaseLogLevel = `${DatabaseType}_${LogLevel}`;
// Esto genera este tipo 👇
// type DatabaseLogLevel = "MySQL_INFO" | "MySQL_WARN" | "MySQL_ERROR" | "PostgreSQL_INFO" | "PostgreSQL_WARN" | "PostgreSQL_ERROR" | "SQLite_INFO" | "SQLite_WARN" | "SQLite_ERROR"

Un uso que les podemos dar es crear un tipo que nos sirva para restringir valores que sigan un patrón en específico:

type Endpoint = '/users' | '/admin';
type HttpMethod = 'POST';

type ValidEnpoint = `${HttpMethod} ${Endpoint}`;
// Esto genera este tipo 👇
// type ValidEnpoint = "POST /users" | "POST /admin"