Type expression

Partial<T>

  • Utility types
  • Tested with TypeScript 5.9

Partial<Product> is Product with every property optional. It fits values that hold some of an object's fields: the changes in an update, user options merged over defaults, a fixture that fills in the rest. TypeScript has had it since version 2.1.

Only the presence of properties is relaxed. A property that is there must still have the right type (TS2322 for price: "17.50"), and an extra property in an object literal is still an error.

At a glance

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

Examples

products.js products.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 {{ sku: string, name: string, price: number, live: boolean }} Product */

/**
 * @param {Product} product
 * @param {Partial<Product>} changes
 * @returns {Product}
 */
export function update(product, changes) {
  return { ...product, ...changes };
}

/** @type {Product} */
const tee = { sku: "TEE-01", name: "Cotton tee", price: 19.5, live: false };
update(tee, { price: 17.5 });
update(tee, { live: true, name: "Organic cotton tee" });
type Product = { sku: string; name: string; price: number; live: boolean };

export function update(product: Product, changes: Partial<Product>): Product {
  return { ...product, ...changes };
}

const tee: Product = { sku: "TEE-01", name: "Cotton tee", price: 19.5, live: false };
update(tee, { price: 17.5 });
update(tee, { live: true, name: "Organic cotton tee" });
Partial<T> for an object of changes.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
products.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: products.js(9,9): error TS2322: Type 'string' 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(9,9): error TS2322: Type 'string' 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(9,9): error TS2322: Type 'string' is not assignable to type 'number'. checked 21 October 2026
/** @typedef {{ sku: string, price: number }} Product */

/** @param {Partial<Product>} changes */
export function patch(changes) {
  return changes;
}

patch({ price: "17.50" });error TS2322: Type 'string' is not assignable to type 'number'.
Partial still checks the types of what is there.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
products.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: products.js(6,10): error TS18048: 'changes.price' is possibly 'undefined'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. products.js(6,10): error TS18048: 'changes.price' is possibly 'undefined'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. products.js(6,10): error TS18048: 'changes.price' is possibly 'undefined'. checked 21 October 2026
/** @typedef {{ sku: string, price: number }} Product */

/** @param {Partial<Product>} changes */
export function priceLabel(changes) {
  return changes.price.toFixed(2);error TS18048: 'changes.price' is possibly 'undefined'.
}
Every property of a Partial may be missing.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Reading a Partial

Every property of a Partial may be undefined, so reading one requires a check: changes.price.toFixed(2) is TS18048, as the third example shows. Merging with a complete object, { ...product, ...changes }, gives back a full Product.

Gotchas

  • Partial is shallow: nested objects keep their required properties.
  • With exactOptionalPropertyTypes, Partial<Product> does not accept { price: undefined }; without it, it does, and the spread then writes undefined over the price.

Questions

How do I make all properties optional in JSDoc?

Wrap the type: @param {Partial<Product>} changes.

Sources

Last reviewed 20 October 2026.