Template Literal Types

Build string literal types by interpolation — typed string patterns at compile time.

Template literal types use backtick syntax in type position to compose string literals, exactly mirroring template strings in values.

type Lang = "en" | "fr";
type Greeting = `hello_${Lang}`; // "hello_en" | "hello_fr"

Feed a union in and the type expands across every combination — a small pattern that generates a lot of precise literal types.

Intrinsic string helpers

TypeScript ships four built-ins for casing: Uppercase, Lowercase, Capitalize, and Uncapitalize. They pair beautifully with template literals to model naming conventions:

type EventName<K extends string> = `on${Capitalize<K>}`;
type T = EventName<"click">; // "onClick"

This is what lets libraries type things like CSS units (`${number}px`), event handler names, and API route strings.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • An event system builds typed event names like 'on:click' | 'on:focus' by template-literal-concatenating a prefix with a union.
  • A CSS-in-TypeScript library generates typed property accessor strings like 'margin-top' from separate scale and direction unions.
  • A routes object uses template literal types to enforce that every route string starts with a slash.

More examples

Concatenate string literals

Defines a template literal type as a pattern; only strings that match the interpolated shape are assignable.

Example · ts
type Greeting = `Hello, ${string}!`;

const a: Greeting = 'Hello, Alice!'; // OK
const b: Greeting = 'Hi, Alice!';    // Error: does not match pattern

Union distribution in template

Template literal types distribute over union members, generating every combination of prefix and side automatically.

Example · ts
type Side  = 'top' | 'bottom' | 'left' | 'right';
type Prop  = `margin-${Side}` | `padding-${Side}`;
// 'margin-top' | 'margin-bottom' | ... | 'padding-right'

function setStyle(prop: Prop, value: string): void {
  console.log(`${prop}: ${value}`);
}

Event name builder

Combines Capitalize<T> with a template literal to derive typed event handler names, and uses key remapping to build the map.

Example · ts
type EventName<T extends string> = `on${Capitalize<T>}`;

type ClickEvent  = EventName<'click'>;  // 'onClick'
type ChangeEvent = EventName<'change'>; // 'onChange'

type HandlerMap = {
  [K in 'click' | 'change' | 'focus' as EventName<K>]: () => void;
};

Discussion

  • Be the first to comment on this lesson.
Template Literal Types — TypeScript | SoundsCode