Three similar spellings mean different things. object (lowercase) accepts any value that is not a primitive: objects, arrays, functions. Object (capitalized) and the empty type {} accept every value except null and undefined, numbers and strings included.
None of them says what properties the value has, so reading item.sku from an object is an error (TS2339). When you know the shape, write it: {{ sku: string, price: number }}, or a @typedef.
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| Any non-primitive | /** @type {object} */ | : object |
| Almost anything | /** @type {Object} */ or /** @type {{}} */ | : Object or : {} |
| A specific shape | /** @type {{ sku: string }} */ | : { sku: string } |
Examples
/** @param {object} options */
export function configure(options) {
return Object.keys(options).length;
}
configure({ theme: "dark" });
configure([1, 2]);
configure(42);error TS2345: Argument of type 'number' is not assignable to parameter of type 'object'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @param {object} item */
export function skuOf(item) {
return item.sku;error TS2339: Property 'sku' does not exist on type 'object'.
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @type {Object} */
let a = 42;
/** @type {{}} */
let b = "text";
// Both accept primitives; only null and undefined are rejected.
a = true;
b = 0;
export { a, b };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Which one to write
Write object for "some object, I only pass it along" (a cache key, an options bag you forward unchanged). Write the shape when you read properties from it. Avoid Object and {}: they look like "an object" but accept 42 and "text", as the third example shows.
In @typedef {object} Name followed by @property lines, object (or Object) is part of the tag syntax: it starts an object type whose properties the following lines describe.
Without noImplicitAny
The handbook notes that with noImplicitAny off, TypeScript reads Object and object in JSDoc as any. With strict, which turns noImplicitAny on, they keep the meanings above, which is what every example on this site uses.
Gotchas
- Arrays and functions are objects:
configure([1, 2])passes anobjectparameter. - For a dictionary with string keys, write
Record<string, T>rather thanobject.
Questions
What is the difference between object and Object in JSDoc?
With strict, object accepts only non-primitive values, while Object accepts any value except null and undefined. Neither lists properties.
Sources
- JSDoc Reference: types · TypeScript handbook
- More on Functions: object · TypeScript handbook
- Object Types · TypeScript handbook
Last reviewed 20 October 2026.