What this tool does
A JSON sample becomes JSDoc typedefs, one block per object.
{ "id": 1, "name": "Ada", "address": { "city": "Paris" } }
/**
* @typedef {Object} Root
* @property {number} id
* @property {string} name
* @property {Address} address
*/
/**
* @typedef {Object} Address
* @property {string} city
*/
Drop them at the top of a .js file and every @type {Root} in that file is checked — by your editor, and by tsc --checkJs if you run it.
A list at the root is named too
/**
* @typedef {Array<UsersItem>} Users
*/
That block used to be missing: an array sample produced the item typedef alone, and the root name you had set went nowhere. It was a real defect, found while writing this page and fixed.
Arrays are always written Array<…> rather than …[]. Both are valid; the long form stays readable when the item type is a union or a *.
A key that is not an identifier
{ "content-type": "text/html" }
* @property {string} "content-type"
The quotes keep the key readable, and they are not standard JSDoc — there is no syntax for a property name that is not a valid identifier. This is stated rather than hidden: nothing in the output will warn you, and an editor may simply ignore that line. A key like this is best renamed at the source.
What a sample cannot decide
Every property is documented as present, because that is what the document showed. JSDoc marks an optional one @property {string} [name], and a nullable one {?string} — both are edits you make once you know the API, not facts a single payload contains.
An unknown value becomes *, which is JSDoc for “any type”. It appears where the sample is silent: an empty array gives Array<*>.
Private by design
Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.