typescript-best-practices
TypeScript best practices. Use when reading or editing any .ts or .tsx file.
- License 许可
- MIT
- 最近更新
- 2026-11-03
- Stars
- ★ 10
- Forks
- 2
01 前言 Front Matter
- name
- typescript-best-practices
- paths
- [ "**/*.ts", "**/*.tsx" ]
- description
- TypeScript best practices. Use when reading or editing any .ts or .tsx file.
- user-invokable
- false
- disable-model-invocation
- false
02 资源文件 1
- 参考文档references/patterns.md9.1 KB
03 SKILL.md 正文
TypeScript best practices
Apply the Contracts section of the engineering-standards principle skill first.
| Rule | Summary |
|---|---|
| Discriminated unions | Model variants with a kind literal discriminant so impossible states can't be represented. No optional-field bags. |
| Branded types | Brand primitives with & { readonly __brand: "X" } so they can't be mixed up. Validate once at the boundary. A brand comes from a verifying type guard (input is AgentId), never from as. |
| Constructive modeling | Build the shape so the illegal value can't be constructed. [T, ...T[]] for non-empty, [T, T][] for even length, start plus duration for a range. Not a runtime guard, not a wish for refinement types. |
| Simplest total type | Keep T[] while every operation on it stays total. Strengthen to NonEmpty<T> only where the loose type forces !, a cast, or a "should never happen" throw. |
unknown over any |
External data is unknown. |
| Schemas before guards | Before hand-writing a property-by-property type guard, use the repository's runtime schema library and infer the type from the schema, such as z.infer. |
No as casts |
Every as is a runtime crash waiting. Cast only after validation. |
| Narrowing hierarchy | Discriminant switch > in operator > typeof/instanceof > user-defined type guard > as. |
| Type guards | Must verify the claim. A lying guard is worse than as because the bug hides behind a name that says it's safe. Name them isX or hasX. |
| Exhaustiveness | Inline const _exhaustive: never = x; in default arms so the compiler errors when a new variant is added. |
satisfies over as |
Validates the value without widening literal types. |
| Boundary validation | Parse where data crosses in, into a named domain type. Record<string, unknown> (however spelled) stops at that parse. Trust types inside. See the boundary-discipline principle skill. |
| Schema-derived types | Reach for Pick/Omit/Parameters/ReturnType/Awaited/typeof before declaring a new interface. |
| Object args | Pass objects, not positional, so argument order is self-documenting. Skip on hot paths (per-frame render, tokenizers, parsers). |
| Real tests | Don't mock what you can run. Prefer the framework's real test primitives with leak/disposable checks, and verify UI in a running build. Mock only what you can't run locally. |
| Structured telemetry | Prefer structured logger diagnostics with enough context to debug from an id. No console.log in shipped code. |
Examples: references/patterns.md.
04 同仓库更多 Skills
changelog
Write the changelog entry for a pull request. Use when a PR changes behavior that users, operators, or integrators can notice.
writing-good-tickets
Write, file, or update an issue or ticket that an agent or a developer can take to one PR. Use when filing a bug or feature, updating an issue, or breaking a plan into tickets.
writing-good-prs
Write or update a pull request title and body that a reviewer can trust and own. Use when opening a PR or editing its description.
writing-good-commits
Write or reword a git commit message and size the commit it describes. Use when committing, or when reshaping commits during a rebase.
writing-for-agents
Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.
wizard
Generate an interactive bash wizard that walks a human through steps only they can perform. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself.