Q28 of 38 · TypeScript

What are template literal types in TypeScript, and what can they express?

TypeScriptSeniortypescripttemplate-literal-typesmapped-typesstring-manipulationadvanced-types

Short answer

Short answer: Template literal types combine string literal types using backtick syntax: `` `get${Capitalize<string & K>}` ``. They enable typed event names, route patterns, CSS property names, getter/setter method names, and any string-structured type — all enforced at compile time.

Detail

Template literal types (TypeScript 4.1) apply template literal string syntax to types, producing new string literal types from combinations.

Basic syntax: ``type EventName = on${string}``` — matches any string starting with "on". Combined with a literal union: ```on${Capitalize<"click" | "focus">}``` produces "onClick" | "onFocus"`.

Built-in string manipulation types: TypeScript ships Capitalize, Uncapitalize, Uppercase, Lowercase for use in template literal types.

Key remapping in mapped types: The most powerful use — generate method names from property names in a mapped type: { [K in keyof T as get${Capitalize<string & K>}]: () => T[K] }

In test automation:

  • Typed event names: page-event:${PageName}
  • Typed CSS custom properties: --${string}
  • Typed API endpoints: /api/${Resource}/${number} (limited but useful)
  • Typed fixture names in Playwright config: ensures fixture keys follow a naming convention

// EXAMPLE

// Basic template literal type
type EventName = `on${"Click" | "Focus" | "Blur"}`;
// "onClick" | "onFocus" | "onBlur"

// Generate getter/setter pairs from a model
interface User { name: string; email: string; age: number; }

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type Setters<T> = {
  [K in keyof T as `set${Capitalize<string & K>}`]: (val: T[K]) => void;
};

type UserAccessors = Getters<User> & Setters<User>;
// { getName: () => string; setName: (val: string) => void; ... }

// Typed CSS custom properties
type CSSCustomProp = `--${string}`;
function setCssProp(el: HTMLElement, prop: CSSCustomProp, val: string) {
  el.style.setProperty(prop, val);
}
setCssProp(el, "--color-primary", "#0D9668"); // ok
// setCssProp(el, "color", "red");           // Error: must start with --

// WHAT INTERVIEWERS LOOK FOR

The template literal type syntax and combination with union types. The string manipulation helpers (Capitalize etc.). Key remapping in mapped types is the most powerful use case. Real-world examples (event names, CSS vars, API routes) show genuine application.

// COMMON PITFALL

Template literal types are purely structural — `\`/api/\${string}\`` matches any string starting with '/api/', but TypeScript cannot parse the string's pattern at runtime. Don't use them to validate URL structures; use runtime validation instead.