Required<Type>

Constructs a type where every property of Type is mandatory, removing all optional markers.

Signature
type Required<Type> = { [Property in keyof Type]-?: Type[Property] }
  • Added in TypeScript 2.8

Parameters

ParameterTypeDescription
$Typeany typeThe source type whose optional properties are made required. Properties that were already required are copied unchanged.

Return value

An object type with the same properties as Type, each mandatoryA mapped type over keyof Type where the `-?` modifier has removed the optional marker from every property.

Errors

Nothing at runtime. The checker errors if a value assigned to the result omits any property.

Changelog

  • PHP 2.8Introduced alongside the `-?` mapped type modifier, which is what makes removing optionality expressible at all.

Required maps over keyof Type with the -? modifier, which subtracts the optional marker from every property. It is the exact inverse of Partial.

When to reach for it

  • Describing the resolved shape of an options object after defaults have been filled in, so the rest of the code never has to null-check.
  • Forcing an exhaustive object literal — a config map or a lookup table where forgetting a key must be a compile error.
  • Asserting the output of a validation step: input is Options, output is Required<Options>.

What trips people up

-? also removes undefined from the property type, but only for properties that were declared with ?. A property written as host: string | undefined — required, but explicitly nullable — keeps its undefined after Required, because there is no optional marker to strip. If you want undefined gone from the value type too, compose with NonNullable.

It is shallow. Nested optional properties stay optional, exactly as with Partial.

It does not create values. The type says every key is present; nothing checks that at runtime. The function that produces the Required value is where the defaults actually have to be supplied.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Type the return value of a `withDefaults()` function so downstream code skips null checks.
  • Force an object literal to list every key of an interface, turning omissions into compile errors.
  • Pair with `Partial` to model the input and output halves of a configuration pipeline.

Frequently asked questions

How do I remove optional properties in TypeScript?

Use `Required<T>`, which maps over the type with the `-?` modifier to strip the `?` from every property. It was added in TypeScript 2.8 together with mapped type modifier subtraction.

Does Required remove undefined from a property type?

Only for properties that were declared optional with `?` — stripping the marker also drops the implicit `undefined`. A property explicitly declared as `x: string | undefined` keeps its `undefined`, because there is no optional marker involved.

Can I make just one property required?

Yes — intersect the parts: `Omit<T, "id"> & Required<Pick<T, "id">>` makes only `id` mandatory while leaving the rest of `T` as-is.

More examples

Optional marker versus an explicit undefined

The first log prints `{ a: 'set', b: undefined }` and type-checks: `Required` removed the `?` from `a` but had nothing to remove from `b`, so `b` still accepts undefined. The hand-written mapped type in the second half applies `NonNullable` to each property as well, and `b: undefined` there would be a compile error.

Example · typescript
interface Mixed {
  a?: string;              // optional
  b: string | undefined;   // required, but may hold undefined
}

type R = Required<Mixed>;
// R is { a: string; b: string | undefined }

const value: R = { a: "set", b: undefined };
console.log(value);

// Compose with NonNullable to close the gap on b
type FullyRequired = { [K in keyof Mixed]-?: NonNullable<Mixed[K]> };
const strict: FullyRequired = { a: "set", b: "also set" };
console.log(strict);

Forcing an exhaustive handler map

The sorted key list prints `onClose`, `onMessage`, `onOpen` and then `message: ping`. Because the literal is annotated `Required<Handlers>`, deleting any one of the three entries fails to compile — and `handlers.onMessage("ping")` needs no optional-call `?.`, since the type guarantees the function is there.

Example · typescript
interface Handlers {
  onOpen?: () => void;
  onMessage?: (data: string) => void;
  onClose?: () => void;
}

// Every hook must be provided — a missing key is a compile error
const handlers: Required<Handlers> = {
  onOpen: () => console.log("open"),
  onMessage: (data) => console.log("message:", data),
  onClose: () => console.log("close"),
};

for (const key of Object.keys(handlers).sort()) {
  console.log("registered:", key);
}

handlers.onMessage("ping");

Discussion

  • Be the first to comment on this lesson.