Type expression

NonNullable<T>

  • Utility types
  • Since TypeScript 2.8

NonNullable<T> is T without null and undefined. NonNullable<Product["discount"]> is number when the discount property is number | null | undefined, which is the right type for the value after ?? 0.

Assigning null to it is an error (TS2322), as the first example shows. TypeScript 2.8 added it with the other predefined conditional types.

At a glance

JSDoc in a .js file TypeScript in a .ts file
/** @type {NonNullable<Product["discount"]>} */ : NonNullable<Product["discount"]>

Examples

products.js products.ts Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: products.js(14,7): error TS2322: Type 'null' is not assignable to type 'number'. products.ts(9,7): error TS2322: Type 'null' is not assignable to type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. products.js(14,7): error TS2322: Type 'null' is not assignable to type 'number'. products.ts(9,7): error TS2322: Type 'null' is not assignable to type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. products.js(14,7): error TS2322: Type 'null' is not assignable to type 'number'. products.ts(9,7): error TS2322: Type 'null' is not assignable to type 'number'. checked 21 October 2026
/** @typedef {{ sku: string, discount: number | null | undefined }} Product */
/** @typedef {NonNullable<Product["discount"]>} Discount */

/**
 * @param {Product} product
 * @returns {Discount}
 */
export function discountOf(product) {
  return product.discount ?? 0;
}

/** @type {Discount} */
const none = null;error TS2322: Type 'null' is not assignable to type 'number'.

export { none };
type Product = { sku: string; discount: number | null | undefined };
type Discount = NonNullable<Product["discount"]>;

export function discountOf(product: Product): Discount {
  return product.discount ?? 0;
}

const none: Discount = null;error TS2322: Type 'null' is not assignable to type 'number'.

export { none };
NonNullable<T> removes null and undefined.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
compact.js 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
/**
 * @template T
 * @param {T[]} items
 * @returns {NonNullable<T>[]}
 */
export function compact(items) {
  return items.filter(/** @returns {item is NonNullable<T>} */ (item) => item != null);
}

const skus = compact(["TEE-01", null, "MUG-07", undefined]);
skus.map((sku) => sku.toLowerCase());
NonNullable in a generic helper.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

In generic helpers

A compact helper that drops empty values returns NonNullable<T>[]. The filter callback needs a type predicate, item is NonNullable<T>, so that TypeScript accepts the narrowed array as the return value; the second example writes it in a JSDoc comment on the arrow function.

Gotchas

  • Without strict or strictNullChecks, null and undefined are not tracked and NonNullable changes nothing visible.
  • It removes only null and undefined; 0, "" and false stay.

Questions

How do I remove null from a type in JSDoc?

{NonNullable<YourType>}, or write the type without null if you control it.

Sources

Last reviewed 20 October 2026.