Skip to content
webtype.org#221 return-type · par 3

No. 221 · July 29, 2026 · Moderate

Return Type

Implement `MyReturnType<T>` so it extracts what a function type returns, whatever parameters it takes. Anything that is not a function returns `never`.

01

Try the puzzle yourself

Par 3

Puzzle

return-type.ts
Stroke 1 of 3Not run yet

Replace ??? — your solution is checked against the cases below. Tab indents; press Escape then Tab to move focus out.

Checks

4
  • MyReturnType<() => string>
    string
  • MyReturnType<(a: number) => boolean>
    boolean
  • MyReturnType<() => void>
    void
  • MyReturnType<string>
    never

How a check is judged Exact type equality, not assignability — an intersection is not the same as the flattened object.

How everyone did

Fewer than 5 people have solved this one so far. The distribution appears once there is enough of a sample to mean anything.

Archive
02

Annotated solution

Published July 30, 2026

The solution

type MyReturnType<T> = T extends (...args: never[]) => infer R ? R : never

The common wrong answer

type MyReturnType<T> = T extends () => infer R ? R : never

A zero-parameter pattern only matches zero-parameter functions, so `(a: number) => boolean` falls through to `never`. The pattern must be permissive about parameters to be permissive about signatures.

Line by line

  1. (...args: never[]) => infer R

    Because parameters are contravariant, a parameter list of `never[]` is assignable *from* every other parameter list. It is the safe way to write "a function of any shape" without reaching for `any`.

  2. infer R

    `infer` in return position asks the compiler to solve for whatever sits there. It is the same mechanism as inferring an element type from an array — only the position changes.

Takeaway

`infer` can be placed anywhere a type can appear inside a pattern. Most of the standard library’s extraction helpers are one conditional with one `infer` in the right spot.