Template literal types build new string types by embedding other types inside a backtick string — identical syntax to JavaScript template literals but operating entirely at the type level.
Template literal types xây dựng string types bằng cách nhúng các kiểu khác vào bên trong backtick string — giống hệt JavaScript template literals nhưng hoạt động hoàn toàn ở cấp độ kiểu. Kết quả là một kiểu string literal mới.
1type Greeting = `Hello, ${string}`;23const a: Greeting = "Hello, world"; // OK4const b: Greeting = "Hello, Alice"; // OK5const c: Greeting = "Hi there"; // Error — does not match pattern67// Embedding a literal type8type EventName = "click" | "focus" | "blur";9type HandlerName = `on${Capitalize<EventName>}`;10// = "onClick" | "onFocus" | "onBlur"1112// Embedding number produces string representation13type GridRow = `row-${number}`;14const r: GridRow = "row-42"; // OKEmbedding a non-literal type like string or number produces a pattern-matching constraint rather than a finite union. TypeScript enforces that any value assigned must match the pattern at compile time.
Khi bạn nhúng một kiểu không phải literal vào template literal (ví dụ string, number, boolean), TypeScript tạo ra kiểu string tương ứng — không phải một union cụ thể mà là một ràng buộc pattern matching.
When a template literal type contains a union, TypeScript automatically computes the Cartesian product — every combination of the member strings.
Khi bạn kết hợp template literal types với union types, TypeScript tự động tạo ra tất cả các tổ hợp có thể. Đây là tính năng cực kỳ mạnh khi tạo ra tập hợp lớn các string constants từ các tập hợp nhỏ hơn.
1type Direction = "top" | "right" | "bottom" | "left";2type Size = "sm" | "md" | "lg";34// All combinations: "top-sm" | "top-md" | "top-lg" | "right-sm" | ...5type Spacing = `${Direction}-${Size}`;67// Useful for CSS utility class names8type Margin = `m${Direction extends string ? Capitalize<Direction> : never}`;9// = "mTop" | "mRight" | "mBottom" | "mLeft"1011// Multiple unions multiply out12type Color = "red" | "blue";13type Shade = "light" | "dark";14type ColorShade = `${Shade}-${Color}`;15// = "light-red" | "light-blue" | "dark-red" | "dark-blue"Tích Descartes của nhiều union có thể tạo ra rất nhiều kết hợp. TypeScript có giới hạn khoảng 100,000 union members — hãy cẩn thận khi kết hợp nhiều union lớn với nhau.
TypeScript ships four compiler-intrinsic string manipulation types. They are implemented at the compiler level and cannot be replicated in user-land TypeScript.
TypeScript cung cấp bốn utility types được tích hợp sẵn để thao tác với string literal types. Chúng được triển khai ở cấp độ compiler và không thể tái tạo trong TypeScript thuần.
1// Uppercase<S> — converts every character to upper case2type U = Uppercase<"hello">; // "HELLO"3type Env = Uppercase<"dev" | "prod">; // "DEV" | "PROD"45// Lowercase<S> — converts every character to lower case6type L = Lowercase<"WORLD">; // "world"78// Capitalize<S> — upper-cases the first character only9type C = Capitalize<"firstName">; // "FirstName"1011// Uncapitalize<S> — lower-cases the first character only12type UC = Uncapitalize<"FirstName">; // "firstName"Combining template literal types with conditional types and infer lets you parse string types — extracting named portions of a string pattern at the type level.
Kết hợp template literal types với conditional types và infer cho phép bạn phân tích cú pháp string types — trích xuất các phần cụ thể của một kiểu string theo pattern.
1// Extract everything after a prefix2type StripPrefix<S extends string, Prefix extends string> =3 S extends `${Prefix}${infer Rest}` ? Rest : S;45type Stripped = StripPrefix<"on:click", "on:">; // "click"6type Same = StripPrefix<"click", "on:">; // "click" (no match, returns S)78// Extract head and tail of a dot-separated path9type Head<S extends string> =10 S extends `${infer H}.${string}` ? H : S;1112type Tail<S extends string> =One of the most practical uses of template literal types is building type-safe event emitter APIs where event names are automatically derived from model names.
Một trong những ứng dụng thực tế nhất của template literal types là xây dựng API event listener type-safe, nơi tên sự kiện được tạo ra tự động từ tên model.
1type EntityEvent<Entity extends string, Action extends string> =2 `${Lowercase<Entity>}:${Action}`;34type UserEvent = EntityEvent<"User", "created" | "updated" | "deleted">;5// = "user:created" | "user:updated" | "user:deleted"67type OrderEvent = EntityEvent<"Order", "placed" | "shipped" | "cancelled">;89type AppEvent = UserEvent | OrderEvent;1011// Type-safe event emitter12declare function on<E extends AppEvent>(Template literal types excel at modelling CSS string patterns — shorthand properties, custom properties, breakpoint variants, and more.
Template literal types xuất sắc trong việc mô hình hóa các string patterns từ CSS — margin shorthand, CSS custom properties, media query breakpoints, và nhiều hơn nữa.
1// CSS custom property names must start with --2type CSSVar = `--${string}`;34declare function setVar(name: CSSVar, value: string): void;5setVar("--primary-color", "#3b82f6"); // OK6setVar("primary-color", "#3b82f6"); // Error — missing --78// Spacing scale: t-shirt sizes mapped to sides9type Side = "top" | "right" | "bottom" | "left" | "x" | "y";10type SpacingScale = 0 | 1 | 2 | 4 | 8 | 16;11type SpacingClass = `p${Side}-${SpacingScale}` | `m${Side}-${SpacingScale}`;12Template literals combined with mapped and conditional types let you model deep nested object paths — a pattern used by React Hook Form, Zod, and similar libraries.
Template literal types kết hợp với mapped types và conditional types cho phép bạn xây dựng kiểu biểu diễn các đường dẫn lồng nhau trong một object — pattern này được dùng trong các thư viện như React Hook Form và Zod.
1type Paths<T, Prefix extends string = ""> =2 T extends object3 ? {4 [K in keyof T]: K extends string5 ? Prefix extends ""6 ? K | Paths<T[K], K>7 : `${Prefix}.${K}` | Paths<T[K], `${Prefix}.${K}`>8 : never;9 }[keyof T]10 : never;1112type Config = {Template literal types dùng cú pháp backtick để xây dựng string types mới từ các kiểu hiện có
Kết hợp với union tạo ra tích Descartes — tất cả các tổ hợp có thể
Uppercase, Lowercase, Capitalize, Uncapitalize are compiler-intrinsic utilitiesUppercase, Lowercase, Capitalize, Uncapitalize là các intrinsic types tích hợp sẵn
infer inside a template literal extracts named portions of a string typeinfer bên trong template literal cho phép trích xuất các phần chuỗi
Ứng dụng thực tiễn: event names type-safe, CSS utility classes, deep object paths
Template literal types hoạt động ở compile time — zero runtime cost