Back to roadmaps typescript Course

Template Literal Types and infer

As your TypeScript skills grow, you will encounter scenarios where you need to parse string combinations or extract types from nested structures. This is where Template Literal Types and the infer keyword shine.


1. Template Literal Types

Template literal types build on string literal types. They allow you to combine and manipulate strings at the type level, using the same syntax as JavaScript template strings.

type World = "world";

// Type evaluates to "hello world"
type Greeting = `hello ${World}`;

Generating Combinations

When unions are passed into template literals, TypeScript generates all possible combinations:

type Vertical = "top" | "bottom";
type Horizontal = "left" | "right";

// Evaluates to: "top-left" | "top-right" | "bottom-left" | "bottom-right"
type Alignment = `${Vertical}-${Horizontal}`;

This is highly useful for styling systems and configuration mapping.


2. Type Inference with infer

The infer keyword can only be used within the conditional check of a conditional type. It allows you to declare a placeholder type variable to be extracted by the compiler.

Extracting Promise Values

Suppose you want to extract the resolution type of a Promise:

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type ResolvedNumber = UnwrapPromise<Promise<number>>; // Evaluates to number
type DirectValue = UnwrapPromise<string>;             // Evaluates to string

In this example, if T is a Promise, TypeScript infers the wrapped type and names it U, then returns U.


3. Real-world Example: Function Return Types

TypeScript uses infer to define its built-in utility types, such as ReturnType.

type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function processOrder() {
  return { orderId: 101, status: "pending" };
}

// Extract the return type of the function
type OrderResult = GetReturnType<typeof processOrder>;

4. Summary

  • Template literal types allow string manipulation and combinatorial matching during compilation.
  • Use template literal unions to construct custom configuration keys.
  • The infer keyword extracts nested types within conditional type checks.
  • Built-in helper types like ReturnType rely on infer to inspect function signatures.
Published on Last updated: