Template Literal Types
Template literal types combine string literal types with embedded expressions to create powerful string pattern types.
Definition
type Greeting = `Hello, ${string}`;
type EventHandler = `on${Capitalize<string>}`;Examples
type CSSUnit = `${number}px` | `${number}em` | `${number}rem`;
const width: CSSUnit = "100px";
const fontSize: CSSUnit = "1.5rem";
// const bad: CSSUnit = "100"; // Error
type HexColor = `#${string}`;
const color: HexColor = "#ff0000";type Resource = "users" | "posts" | "comments";
type Method = "get" | "create" | "update" | "delete";
type ApiEndpoint = `/api/${Resource}`;
type ApiAction = `${Method}${Capitalize<Resource>}`;
// "getUsers" | "getPosts" | ... | "deleteComments"
type ApiClient = {
[K in ApiAction]: () => Promise<unknown>;
};
// { getUsers: () => Promise<unknown>; createUsers: () => Promise<unknown>; ... }type Dot<T extends string, U extends string> = `${T}.${U}`;
type Paths = "user.name" | "user.email" | "settings.theme";
type PathParts<T extends string> =
T extends `${infer Head}.${infer Tail}`
? { head: Head; tail: Tail }
: { head: T; tail: never };
type Result = PathParts<"user.name">;
// { head: "user"; tail: "name" }Common Use Cases
- 1Defining string pattern types for CSS values and URLs
- 2Generating API method names from resource unions
- 3Parsing and validating string formats at the type level
- 4Creating type-safe route definitions
- 5Building DSLs with string-based type patterns
Understanding Template Literal Types
Template literal types, introduced in TypeScript 4.1, bring the power of JavaScript template strings to the type system. They use the same backtick syntax but operate on types instead of values, enabling string pattern matching and generation at compile time.
At their simplest, template literal types create string patterns. `${number}px` matches any string that is a number followed by "px"—like "100px" or "3.14px". This is powerful for CSS values, URL patterns, and other domain-specific string formats.
When combined with union types, template literal types generate the Cartesian product of all possibilities. If you have type Color = "red" | "blue" and type Size = "sm" | "lg", then `${Size}-${Color}` produces "sm-red" | "sm-blue" | "lg-red" | "lg-blue". This automatic expansion is transformative for generating comprehensive type sets from smaller building blocks.
Template literal types also support inference with the infer keyword in conditional types. You can pattern-match strings: T extends `on${infer Event}` ? Event : never extracts the event name from handler names like "onClick" → "Click". This parsing capability enables bidirectional type transformations.
Combined with mapped types and key remapping (the as clause), template literal types enable automatic generation of interface shapes. You can create types where getter and setter method names are derived from property names, event handler types are derived from event names, or API client methods are derived from route definitions.
Template literal types are a cornerstone of modern TypeScript meta-programming. Libraries like ts-pattern, Hono, and tRPC use them to provide type-safe APIs that adapt to your specific application structure.
Related Types
Capitalize<S>Converts the first character of a string literal type to uppercase while leaving the rest unchanged.
Uppercase<S>Converts each character in a string literal type to its uppercase equivalent using intrinsic compiler support.
Lowercase<S>Converts each character in a string literal type to its lowercase equivalent using intrinsic compiler support.
Uncapitalize<S>Converts the first character of a string literal type to lowercase while leaving the rest unchanged.
Mapped TypesMapped types iterate over the keys of a type to create a new type by transforming each property, enabling systematic type transformations.
More String Types
Explore TypeScript Types
Browse our complete reference of 30 TypeScript utility types with definitions, examples, and explanations.