infer & Derived Types

The Course
•
4 min read

Inside a conditional’s matching branch, infer names a type the checker can extract from a pattern. T extends readonly (infer Item)[] ? Item : never asks whether T is an array and, if so, captures its element type as Item. Infer is not a runtime variable or a validation step.

Use parentheses around infer Item in this array pattern so it is easy to read: first identify the array, then its element. A mutable array also fits the readonly array pattern. The fallback never says this helper intentionally has no result for a non-array input.

The same idea underlies standard helpers such as ReturnType for functions and Awaited for asynchronous results. Prefer built-in helpers rather than writing a recursive promise unwrapper from memory. Today we use one small array extractor so you can read a library declaration with confidence.

Deriving a type avoids two annotations drifting apart, but it also couples the consumer to the source shape. Name a stable public contract when you want to control changes. Do not reach for a complex type puzzle when an explicit parameter is clearer.

Predict, check, and run

Write the output before running. Use Check types first, then Check & run. Types disappear at runtime: explain both what the compiler checks and what the code actually does. Each editor is an independent ES module; await asynchronous work explicitly.

Predict, then runTypeScript
type ItemOf<T> = T extends readonly (infer Item)[] ? Item : never;

const title: ItemOf<readonly string[]> = "Types";
const pages: ItemOf<number[]> = 120;

console.log(title, pages);

Enable JavaScript to edit and type-check this example.

Check your prediction
Types 120

Read the compiler error

Predict the rejected relationship before checking. Read the real diagnostic and its source location; fix the contract or the value instead of hiding it with an assertion.

Find and fix the type errorTypeScript
type ItemOf<T> = T extends readonly (infer Item)[] ? Item : never;

const title: ItemOf<string[]> = 25;

console.log(title);

Enable JavaScript to edit and type-check this example.

Check your diagnosis

Item is string for string[]. Inferring a type does not convert the assigned number into text.

Build it yourself

Exercise

infer & Derived Types: practise

Write ValueOfBox<T> that extracts V from {value: V}, otherwise never. Declare a numeric extracted value, print 25, and explain what happens for a record without value.

Your workspaceTypeScript
// Start from the stated contract. Add a valid call and an edge case.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

Put infer in the property pattern, not in the type parameter list.

Hint 2: a first step

The successful branch can return the captured type name.

Show one solution
One possible solutionTypeScript
type ValueOfBox<T> = T extends { value: infer V } ? V : never;

const pages: ValueOfBox<{ value: number }> = 25;

console.log(pages);

Enable JavaScript to edit and type-check this example.

25

Trace the implementation against the task before comparing styles. A passing example supports that case; use the changes below to challenge the wider contract.

Read ReturnType before using it

ReturnType<F> is a built-in helper that extracts a function’s declared or inferred return type. Pass a function type, not a call result. In ReturnType<typeof makeBook>, typeof is the type query from intermediate; it does not invoke makeBook. This example is synchronous. Day 5 adds Awaited for promises.

Derive a function resultTypeScript
function makeBook() {
  return { title: "Types", pages: 120 };
}

type Book = ReturnType<typeof makeBook>;

const book: Book = makeBook();

console.log(book.title, book.pages);

Enable JavaScript to edit and type-check this example.

Check your prediction
Types 120

Change it and test it

Try {value:string}|{value:number} and predict the extracted union. Then use ReturnType<typeof aFunction> on a small function and compare the result to a handwritten alias.

Was this article helpful?

Your response is saved on this device.