Files
2026-05-03 10:12:42 +08:00

238 lines
6.8 KiB
Markdown

---
name: jsdoc
description: 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 `@example` format 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
```typescript
/**
* @example Required parameter
* `name: Type`
*
* @example Optional parameter
* `name?: Type`
*/
```
### Multi-line — fenced code block immediately after `@example`
````typescript
/**
* @example
* ```ts
* const result = buildParams(node, {
* paramsType: 'inline',
* })
* ```
*/
````
### Multiple variants — use multiple `@example` blocks
```typescript
/**
* @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` — use `type` or `interface`
-`@default undefined` — optional (`?`) already implies this
---
## Documentation Patterns
### Simple property — always multi-line
```typescript
/**
* Output directory for generated files.
*/
outDir?: string
```
> ❌ Never use single-line `/** description */` — always expand to multi-line.
### Property with non-obvious default
```typescript
/**
* 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 false` or `@default undefined` when the TypeScript type already makes the default obvious.
### Enum / union with options
```typescript
/**
* 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
```typescript
/**
* 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
```typescript
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:
```typescript
// ✅ 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 `@default` only when the default is non-obvious (not `undefined`, not `false`)
- Use multiple `@example` blocks to show different variants or modes
- Keep `@example` labels 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 `@example` line: `@example \`foo: string\`` → move code to next line
- Use `@param` or `@returns` tags
- Over-document trivial, self-explanatory properties
---
## Tag Order
For consistency, use this order within a JSDoc block:
1. Description (required)
2. Bullet-list of variants or behaviours (if applicable)
3. `@default` (if non-obvious)
4. `@example` (one or more)
5. `@note` (if needed)
6. `@deprecated` (if applicable)
7. `@see` (if providing references)