Tipos de literales de plantilla en TypeScript

Los tipos de literales de plantilla se construyen sobre los tipos de literales de cadena y permiten generar nuevos tipos de cadena mediante interpolación.

Esto permite que TypeScript realice una verificación de tipos más precisa de las cadenas, y es adecuado para escenarios como nombres de eventos, rutas, nombres de clases, etc.


Diagrama SVG: Tipos de literales de plantilla Fondo Título Principio de funcionamiento de los tipos de literales de plantilla Tipo de entrada Tipo de entrada type Event = "click" | "focus" type Method = "get" | "post" Flecha Plantilla Literal de plantilla Tipo de literal de plantilla type Name = `on${Capitalize}` type Path = `${Method}:/${string}` Flecha Tipo de salida Tipo de salida "onClick" "onFocus" "get:/..." Parte inferior: Tipos de utilidad integrados Tipos de utilidad integrados Uppercase "hello" → "HELLO" Lowercase "HELLO" → "hello" Capitalize "hello" → "Hello" Uncapitalize "Hello" → "hello" Marcador de flecha

¿Por qué se necesitan los tipos de literales de plantilla?

En el desarrollo, a menudo necesitamos manejar cadenas formateadas, como nombres de eventos (onClick), rutas de API (get:/users), nombres de clases CSS (btn-primary-md), etc.

Usar el tipo string común no puede describir con precisión estos formatos, mientras que los tipos de literales de plantilla nos permiten definir con precisión el tipo de estas cadenas.

Esto mejora enormemente la seguridad de tipos de TypeScript y reduce los errores en tiempo de ejecución.

Explicación del concepto:Los tipos de literales de plantilla utilizan comillas invertidas (`` ` ``) y${}sintaxis de interpolación para definir tipos de cadena, similar a las plantillas de cadena de JavaScript, pero a nivel de tipos.


Sintaxis básica

Los tipos de literales de plantilla usan comillas invertidas e interpolación para definir tipos.

Ejemplo

// Definir un tipo de literal de cadena básico
type World = "world";

// Usar un tipo de literal de plantilla
// `Hello ${World}` equivale a "Hello world"
type Greeting = `Hello ${World}`;

// Solo se pueden asignar cadenas que cumplan con la definición del tipo
var greeting: Greeting = "Hello world";
console.log(Saludo: + greeting);

Resultado de ejecución:

问候: Hello world

Explicación:Los tipos de literales de plantilla reemplazan las posiciones de interpolación por cadenas reales, generando nuevos tipos literales.


Tipos de utilidad integrados

TypeScript proporciona cuatro tipos de utilidad integrados para manejar mayúsculas y minúsculas de cadenas.

Ejemplo

// Uppercase: convierte la cadena a mayúsculas
type UpperHello = Uppercase<"hello">;  // "HELLO"

// Lowercase: convierte la cadena a minúsculas
type LowerHELLO = Lowercase<"HELLO">;  // "hello"

// Capitalize: convierte la primera letra de la cadena a mayúscula
type CapitalizedHello = Capitalize<"hello">;  // "Hello"

// Uncapitalize: convierte la primera letra de la cadena a minúscula
type UncapitalizedHello = Uncapitalize<"Hello">;  // "hello"

console.log("Uppercase: " + UpperHello);
console.log("Lowercase: " + LowerHELLO);
console.log("Capitalize: " + CapitalizedHello);
console.log("Uncapitalize: " + UncapitalizedHello);

Resultado de ejecución:

Uppercase: HELLO
Lowercase: hello
Capitalize: Hello
Uncapitalize: hello

Escenarios de aplicación:Estos tipos de utilidad son muy útiles en escenarios donde se requiere un formato uniforme, como nombres de eventos, nombres de métodos, etc.


Tipos de eventos

Usando tipos de literales de plantilla se pueden definir con precisión los tipos de nombres de eventos.

Ejemplo

// Construir el tipo de nombre de evento
// `on${Capitalize<string>}` genera una cadena que comienza con "on" y tiene la primera letra en mayúscula
type EventName = `on${Capitalize<string>}`;
// `handle${Capitalize<string>}` genera una cadena que comienza con "handle" y tiene la primera letra en mayúscula
type Handler = `handle${Capitalize<string>}`;

// Solo se pueden asignar cadenas que cumplan con el formato
var clickEvent: EventName = "onClick";
var focusEvent: EventName = "onFocus";
var handler: Handler = "handleSubmit";

console.log(Evento: + clickEvent);
console.log(Manejador: + handler);

Resultado de ejecución:

事件: onClick
处理器: handleSubmit

Ventajas:Con los tipos de literales de plantilla, formatos incorrectos como "onclick" (en minúsculas) serán rechazados por TypeScript.


Tipos de rutas

Usando tipos de literales de plantilla se pueden definir con precisión los tipos de rutas de API.

Ejemplo

// Definir el tipo de método HTTP
type HttpMethod = "get" | "post" | "put" | "delete";

// Definir el formato de ruta
type ApiEndpoint = `/${string}`;  // Cadena que comienza con una barra diagonal

// Combinar en un tipo de ruta de API completo
type ApiPath = `${HttpMethod}${ApiEndpoint}`;

// Solo se pueden asignar rutas que cumplan con el formato
var getUsers: ApiPath = "/get/users";
var createUser: ApiPath = "/post/users";

console.log(Ruta: + getUsers);
console.log(Ruta: + createUser);

Resultado de ejecución:

路径: /get/users
路径: /post/users

Seguridad de tipos:Rutas como "/users" (sin prefijo de método) provocarán un error en TypeScript.


Ejemplo complejo

Los tipos de literales de plantilla pueden combinar múltiples tipos unión, generando todas las combinaciones posibles.

Ejemplo

// Tipo de plantilla con números
// ${number} coincide con cualquier número
type Row = `row${number}`;
type Row10 = Row;  // row0, row1, row2... hasta row9...

// Combinar múltiples tipos
type Variant = "primary" | "secondary";
type Size = "sm" | "md" | "lg";
// Esto genera 6 combinaciones: btn-primary-sm, btn-primary-md, btn-primary-lg...
type ClassName = `btn-${Variant}-${Size}`;

// Solo se puede asignar una de las 6 combinaciones generadas
var className: ClassName = "btn-primary-md";
console.log(Nombre de clase: + className);

Resultado de ejecución:

类名: btn-primary-md

Explosión de combinaciones:Los tipos de literales de plantilla expanden automáticamente todas las combinaciones. Si el tipo unión tiene muchas opciones, el tipo generado puede ser muy grande.


Tipos de utilidad personalizados

Se pueden crear tus propios tipos de utilidad de literales de plantilla.

Ejemplo

// Tipo de utilidad para agregar un prefijo
// T es una cadena arbitraria, P es el prefijo a agregar
type Prefix<T extends string, P extends string> = `${P}${Capitalize<T>}`;

// Tipo de utilidad para agregar un sufijo
// T es una cadena arbitraria, S es el sufijo a agregar
type Suffix<T extends string, S extends string> = `${Capitalize<T>}${S}`;

// Usar un tipo de utilidad personalizado
type HandlerName = Prefix<"click", "on">;
type ButtonId = Suffix<"submit", "Btn">;

var handler: HandlerName = "onClick";
var id: ButtonId = "SubmitBtn";

console.log(Manejador: + handler);
console.log("ID: " + id);

Resultado de ejecución:

处理器: onClick
ID: SubmitBtn

Plantilla genérica:Los tipos de literales de plantilla se pueden combinar con genéricos para crear tipos de utilidad reutilizables.


Consideraciones

  • Tipos de interpolación:En la plantilla,${}puede ser una cadena concreta, un tipo unión, string, number, etc.
  • Cantidad de combinaciones:Al combinar múltiples tipos unión, el tipo generado puede ser muy grande.
  • Manejo de mayúsculas y minúsculas:Usar los tipos de utilidad integrados para manejar mayúsculas y minúsculas de cadenas.

Mejores prácticas:Usar tipos de literales de plantilla para manejar cadenas con formato fijo como nombres de eventos, rutas, nombres de clases, etc., permite obtener una mejor seguridad de tipos.


Resumen

Los tipos de literales de plantilla son parte del potente sistema de tipos de TypeScript.

  • Sintaxis de plantilla:Usar${T}interpolación para construir tipos.
  • Utilidades integradas:Uppercase、Lowercase、Capitalize、Uncapitalize
  • Escenarios de aplicación:Nombres de eventos, rutas de API, nombres de clases CSS, etc.
  • Personalización:Crear tipos de utilidad reutilizables.

Sugerencia:En escenarios que requieran cadenas formateadas, prioriza el uso de tipos de literales de plantilla para obtener verificación de tipos en tiempo de compilación.


Otras extensiones