Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Template Literal Types in TypeScript

Template Literal Types

~13 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

To wrap up Phase 4: template literal types bring JavaScript's template strings (`Hello ${name}`) to the TYPE level – string patterns TypeScript can check at compile time.

The basic syntax

type EventName = `on${string}`;

let a: EventName = 'onClick';   // ✓
let b: EventName = 'onChange';  // ✓
let c: EventName = 'click';     // ✗ error - doesn't start with 'on'

`on${string}` is a TYPE that accepts ANY string STARTING with 'on'${string} inside the template literal type works like a placeholder for "some string", just like normal template strings do at runtime.

Combining with literal unions: generating all variants

type Action = 'borrow' | 'return' | 'reserve';
type EventName = `medium-${Action}`;
// Automatically PRODUCES: 'medium-borrow' | 'medium-return' | 'medium-reserve'

function sendEvent(name: EventName): void {
  console.log(`Event sent: ${name}`);
}

sendEvent('medium-borrow');  // ✓
sendEvent('medium-donate');  // ✗ error - 'donate' is not a valid Action

When a template literal type gets combined with a LITERAL UNION (chapter 10), TypeScript AUTOMATICALLY produces the FULL combination of all possible values – from 3 possible Action values, 3 possible EventName values are generated automatically, without you having to write them out individually.

In practice: a type-safe event system for the library

src/types/LibraryEvents.ts
export type MediumAction = 'borrowed' | 'returned' | 'reserved' | 'added';

export type LibraryEventName = `medium-${MediumAction}`;

export type LibraryEventHandler = (eventName: LibraryEventName, isbn: string) => void;
function logEvent(eventName: LibraryEventName, isbn: string): void {
  console.log(`[${new Date().toISOString()}] ${eventName}: ${isbn}`);
}

logEvent('medium-borrowed', '978-0-618-64015-7');  // ✓
logEvent('medium-lost', '978-0-618-64015-7');      // ✗ error - typo caught IMMEDIATELY

Bonus: built-in string manipulation types

type Capitalized = Capitalize<'hello'>;    // 'Hello'
type Lowered = Lowercase<'HELLO'>;         // 'hello'
type Uppered = Uppercase<'hello'>;         // 'HELLO'
type Uncapitalized = Uncapitalize<'Hello'>; // 'hello'

// Practically combined with chapter 21's key remapping:
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

Capitalize/Lowercase/Uppercase/Uncapitalize are built-in template-literal helper types for exactly this use case – the line from chapter 21 now makes complete sense: string & K ensures K (the abstract key type from keyof T) can actually be treated as a string BEFORE Capitalize gets applied to it.

Achtung: Template literal types are powerful, but with EXCESSIVE use (very long, deeply nested patterns), error messages can become UNREADABLE and compile time can noticeably increase. Use them deliberately for GENUINE string patterns (event names, CSS classes, route paths), not as a general-purpose replacement for normal string validation that's needed at RUNTIME anyway (see chapter 25, error handling).

Tipp: That wraps up Phase 4 (advanced types) – generics, type narrowing, utility types, mapped types, conditional types, template literal types. Phase 5 turns to the PRACTICAL side: modules, error handling, async/await, tooling, and testing – all applied to our now considerably grown library management system.