public-rules › TypeScript techs/typescript

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.