feat: adding JSDoc
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
---
|
||||
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)
|
||||
Reference in New Issue
Block a user