Skip to main content
Practice Problems

Template literal types in TypeScript

What are Template Literal Types?

Template literal types build on string literal types using template literal syntax (\...``) to create new string literal types through string concatenation at the type level.


Basic Syntax

typescript
type Greeting = `Hello, ${string}`; const a: Greeting = "Hello, World"; // ✅ const b: Greeting = "Hello, Alice"; // ✅ const c: Greeting = "Hi, World"; // ❌ Error

Combining Literal Unions

typescript
type Color = "red" | "blue" | "green"; type Size = "small" | "large"; type ColorSize = `${Size}-${Color}`; // "small-red" | "small-blue" | "small-green" | "large-red" | "large-blue" | "large-green"

TypeScript generates all possible combinations — this is called a distributive template literal type.

Built-in String Manipulation Types

typescript
type Upper = Uppercase<"hello">; // "HELLO" type Lower = Lowercase<"HELLO">; // "hello" type Cap = Capitalize<"hello">; // "Hello" type Uncap = Uncapitalize<"Hello">; // "hello" // Combined with template literals type EventName = "click" | "focus" | "blur"; type HandlerName = `on${Capitalize<EventName>}`; // "onClick" | "onFocus" | "onBlur"

Practical Use Cases

CSS Utility Classes

typescript
type Spacing = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8; type Direction = "t" | "b" | "l" | "r" | "x" | "y"; type PaddingClass = `p${Direction}-${Spacing}`; // "pt-0" | "pt-1" | ... | "py-8" type MarginClass = `m${Direction}-${Spacing}`;

Type-safe Event Emitter

typescript
type Events = { userCreated: { id: string; name: string }; userDeleted: { id: string }; orderPlaced: { orderId: string; total: number }; }; type EventHandler<T extends keyof Events> = (data: Events[T]) => void; type OnMethod = `on${Capitalize<string & keyof Events>}`; // "onUserCreated" | "onUserDeleted" | "onOrderPlaced"

API Route Types

typescript
type ApiVersion = "v1" | "v2"; type Resource = "users" | "posts" | "comments"; type ApiRoute = `/api/${ApiVersion}/${Resource}`; // "/api/v1/users" | "/api/v1/posts" | ... | "/api/v2/comments" type IdRoute = `${ApiRoute}/${string}`; // "/api/v1/users/..." etc.

Object Key Patterns

typescript
type GetterName<T extends string> = `get${Capitalize<T>}`; type SetterName<T extends string> = `set${Capitalize<T>}`; type Getters<T> = { [K in keyof T as GetterName<string & K>]: () => T[K]; }; type Setters<T> = { [K in keyof T as SetterName<string & K>]: (value: T[K]) => void; }; interface Person { name: string; age: number; } type PersonGetters = Getters<Person>; // { getName: () => string; getAge: () => number } type PersonSetters = Setters<Person>; // { setName: (value: string) => void; setAge: (value: number) => void }

Inferring Within Template Literals

typescript
type ExtractRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractRouteParams<Rest> : T extends `${string}:${infer Param}` ? Param : never; type Params = ExtractRouteParams<"/users/:userId/posts/:postId">; // "userId" | "postId"

Important:

Template literal types are a powerful feature for creating type-safe string patterns. They're widely used for event names, CSS classes, API routes, and key remapping in mapped types. Combined with Capitalize, Uppercase, etc., they enable expressive type-level string manipulation.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems