Use template literal types for patterned strings
LOW-MEDIUM1.0.0
When to apply Before writing, changing, or reviewing TypeScript types for strings that follow a pattern, such as API paths, translation keys, CSS class or color tokens, or event names.
When a string must follow a known pattern built from a fixed set of parts, type it with a template literal type instead of string.
Implementation
- Build the type from existing unions, such as
type ApiEndpoint = `/api/${ApiRoute}`. - Use it for API paths, translation keys, design tokens, and event names that code constructs or accepts.
- Template literal types check the string's shape, not whether the value is otherwise valid;
${number}accepts any numeric text. Validate strings from outside the program at runtime. - Avoid deeply computed template types, such as modeling SQL queries; they slow the compiler and are hard to read.
Rationale
A string accepts any typo, such as '/api/usersss', and the error appears only when the request fails.
A template literal type turns the typo into a compile error and gives editor completion for the valid values.
Examples
Incorrect (counterexample):
const userEndpoint: string = '/api/usersss';
Correct:
type ApiRoute = 'users' | 'posts' | 'comments';
type ApiEndpoint = `/api/${ApiRoute}`;
const userEndpoint: ApiEndpoint = '/api/users';
'/api/usersss' no longer compiles.
Validation
Review string parameters and fields that must follow a pattern, and check whether a template literal type can express it.
A free-form string, such as a user's display name, should stay string.