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
/** @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" });jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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'.
}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
Partialis shallow: nested objects keep their required properties.- With
exactOptionalPropertyTypes,Partial<Product>does not accept{ price: undefined }; without it, it does, and the spread then writesundefinedover the price.
Questions
How do I make all properties optional in JSDoc?
Wrap the type: @param {Partial<Product>} changes.
Sources
- Utility Types: Partial<Type> · TypeScript handbook
Last reviewed 20 October 2026.