typescriptlisted
Install: claude install-skill smnatale/dotfiles
# TypeScript
TypeScript taste that should hold everywhere. Repo-specific or lint-enforced rules belong in that repo's own CLAUDE.md.
| Rule | Summary |
|------|---------|
| No `any` | Prefer `unknown` and narrow, or a precise type. `any` opts out of the type checker; treat it as always fixable. |
| Illegal states unrepresentable | Model variants with a discriminated union (`kind`/`type` literal tag), not optional-field bags or scattered booleans. |
| Readonly by default | Default to `readonly` on object properties, arrays (`readonly T[]`), and parameters. Drop it only where mutation is genuinely intended. |
| Explicit return types on exports | Annotate the return type of exported/public functions. Let TypeScript infer everything internal. |
| No non-null assertions | Avoid `!`. Narrow or use optional chaining instead. If truly unavoidable, add a one-line justification comment. |
| Literal unions over enums | Default to a string-literal union, plus a `satisfies`-checked const object when you need iteration or lookup. Use a TS `enum` only when the surrounding codebase already uses enums. |
| Derive, don't duplicate | Build related types from one canonical source with `Pick`/`Omit`/`Partial`, etc., instead of hand-copying a shape. |
| Named exports only | Never `export default`. Named exports survive renames and refactors without silently changing the import name. |
| Validate at the boundary | Parse and validate external data (API responses, user input) where it enters the sy