Type expression

Required<T>

  • Utility types
  • Since TypeScript 2.8

Required<PriceOptions> is PriceOptions with the ? removed from every property. It describes an options object after defaults have been applied: callers pass a partial object, and the code inside works with a complete one.

A value missing any property is an error (TS2741, "Property 'digits' is missing…"), as the second example shows.

At a glance

JSDoc in a .js file TypeScript in a .ts file
/** @type {Required<PriceOptions>} */ : Required<PriceOptions>

Examples

options.js options.ts TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/** @typedef {{ currency?: string, digits?: number }} PriceOptions */

/** @type {Required<PriceOptions>} */
const DEFAULTS = { currency: "USD", digits: 2 };

/**
 * @param {number} amount
 * @param {PriceOptions} [options]
 */
export function formatPrice(amount, options) {
  /** @type {Required<PriceOptions>} */
  const { currency, digits } = { ...DEFAULTS, ...options };
  return `${currency} ${amount.toFixed(digits)}`;
}

formatPrice(19.5, { digits: 0 });
type PriceOptions = { currency?: string; digits?: number };

const DEFAULTS: Required<PriceOptions> = { currency: "USD", digits: 2 };

export function formatPrice(amount: number, options?: PriceOptions) {
  const { currency, digits }: Required<PriceOptions> = { ...DEFAULTS, ...options };
  return `${currency} ${amount.toFixed(digits)}`;
}

formatPrice(19.5, { digits: 0 });
Required<T> after filling in defaults.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
options.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: options.js(5,7): error TS2741: Property 'digits' is missing in type '{ currency: string; }' but required in type 'Required<PriceOptions>'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. options.js(5,7): error TS2741: Property 'digits' is missing in type '{ currency: string; }' but required in type 'Required<PriceOptions>'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. options.js(5,7): error TS2741: Property 'digits' is missing in type '{ currency: string; }' but required in type 'Required<PriceOptions>'. checked 21 October 2026
/** @typedef {{ currency?: string, digits?: number }} PriceOptions */

/** @type {Required<PriceOptions>} */
const DEFAULTS = { currency: "USD" };error TS2741: Property 'digits' is missing in type '{ currency: string; }' but required in type 'Required<PriceOptions>'.

export { DEFAULTS };
Required<T> makes every property mandatory.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

The defaults pattern

Declare the defaults as Required<Options> so TypeScript makes you supply every one, then spread the caller's options over them. The result can be typed Required<Options> too, and inside the function no property needs an undefined check.

Gotchas

  • With exactOptionalPropertyTypes on, Required removes the ? but keeps an undefined written into the type: digits?: number | undefined becomes digits: number | undefined. With it off, the result is digits: number.
  • Like Partial, it is shallow.

Questions

What is the opposite of Partial<T>?

Required<T>, which makes every property mandatory.

Sources

Last reviewed 20 October 2026.