6.8 KiB
6.8 KiB
name, description
| name | description |
|---|---|
| jsdoc | Guidelines for writing minimal, high-quality JSDoc comments in TypeScript. |
JSDoc Skill
This skill provides focused guidelines for writing JSDoc comments consistently across the codebase.
When to Use
- Documenting exported type properties and configuration options
- Adding context that TypeScript types don't convey on their own
- Providing usage examples for non-obvious or multi-variant APIs
- Writing inline documentation for generated docs
What It Does
- Defines
@exampleformat conventions (label + inline backtick or fenced block) - Ensures every exported type and property has meaningful documentation
- Avoids redundant tags that duplicate TypeScript type information
- Ensures consistent documentation style across all packages
@example Format
Short one-liner — label on the @example line, code as inline backtick on the next line
/**
* @example Required parameter
* `name: Type`
*
* @example Optional parameter
* `name?: Type`
*/
Multi-line — fenced code block immediately after @example
/**
* @example
* ```ts
* const result = buildParams(node, {
* paramsType: 'inline',
* })
* ```
*/
Multiple variants — use multiple @example blocks
/**
* @example Object mode
* `{ id, data, params }: { id: string; data: Data; params?: QueryParams }`
*
* @example Inline mode
* `id: string, data: Data, params?: QueryParams`
*/
Rules
| Rule | ✅ Correct | ❌ Incorrect |
|---|---|---|
| Label + inline code | @example Required\n\name: Type`` |
@example \name: Type`` (code on tag line) |
| Multi-line code | Fenced ```ts ``` block |
Bare code lines without a fence |
| Short examples | Inline backtick | Triple-backtick fence (too heavy) |
| One concern per example | Separate @example blocks |
One example covering all cases |
Tags
Use Frequently
| Tag | Purpose | Notes |
|---|---|---|
@default |
Default value | Only when default is non-obvious; omit for undefined |
@example |
Usage example | Prefer for complex or multi-variant APIs |
@note |
Important caveat | Version info, breaking changes |
@deprecated |
Mark as deprecated | Include migration path |
Use Sparingly
| Tag | Purpose |
|---|---|
@see |
Reference external docs |
@internal |
Internal API |
@beta |
Experimental |
Avoid (TypeScript Provides)
- ❌
@param— use TypeScript parameter types - ❌
@returns— use TypeScript return type - ❌
@type— use TypeScript type annotation - ❌
@typedef— usetypeorinterface - ❌
@default undefined— optional (?) already implies this
Documentation Patterns
Simple property — always multi-line
/**
* Output directory for generated files.
*/
outDir?: string
❌ Never use single-line
/** description */— always expand to multi-line.
Property with non-obvious default
/**
* Maximum number of concurrent callbacks during traversal.
* Higher values overlap I/O-bound work; lower values reduce memory pressure.
*
* @default 30
*/
concurrency?: number
Do not add
@default falseor@default undefinedwhen the TypeScript type already makes the default obvious.
Enum / union with options
/**
* How path parameters are emitted in the function signature.
* - `'object'` groups them as a single destructured parameter
* - `'inline'` spreads them as individual parameters
* - `'inlineSpread'` emits a single rest parameter
*/
pathParamsType: 'object' | 'inline' | 'inlineSpread'
Property with example
/**
* Applies a uniform transformation to every resolved type string.
* Use this for framework-level type wrappers.
*
* @example Wrap every type in a reactive container
* `typeWrapper: (t) => \`Reactive<${t}>\``
*/
typeWrapper?: (type: string) => string
Nested properties — every field gets its own multi-line JSDoc
names?: {
/**
* Name for the request body parameter.
* @default 'data'
*/
data?: string
/**
* Name for the query parameters group parameter.
* @default 'params'
*/
params?: string
/**
* Name for the header parameters group parameter.
* @default 'headers'
*/
headers?: string
}
Function documentation
Only add JSDoc when it adds value beyond the signature:
// ✅ No JSDoc needed — signature is self-explanatory
function camelCase(str: string): string { ... }
// ✅ JSDoc adds value — explains behaviour and non-obvious edge cases
/**
* Returns `true` when the schema resolves to a plain string output.
*
* - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings.
* - `date` and `time` are plain strings when their `representation` is `'string'`.
*
* @example UUID resolves to a plain string
* `isStringType(uuidSchema) // true`
*
* @example Date with date representation is not a plain string
* `isStringType(dateSchema) // false`
*/
function isStringType(node: SchemaNode): boolean { ... }
Guidelines
✅ DO:
- Document what the property does, not its TypeScript type
- Give every exported type, property, and function a JSDoc comment
- Always use multi-line JSDoc blocks — never single-line
/** ... */ - Use concrete, full-sentence descriptions — not "Enum schema." or "Boolean value."
- Include
@defaultonly when the default is non-obvious (notundefined, notfalse) - Use multiple
@exampleblocks to show different variants or modes - Keep
@examplelabels short and descriptive
❌ DON'T:
- Write single-line
/** description */— always use multi-line - Write
@default undefined— optional?already implies this - Put code directly on the
@exampleline:@example \foo: string`` → move code to next line - Use
@paramor@returnstags - Over-document trivial, self-explanatory properties
Tag Order
For consistency, use this order within a JSDoc block:
- Description (required)
- Bullet-list of variants or behaviours (if applicable)
@default(if non-obvious)@example(one or more)@note(if needed)@deprecated(if applicable)@see(if providing references)