# Typescript Best Practices

> Apply focused TypeScript type, boundary, module, and test guidance. Use when $poteto-mode reads or edits .ts or .tsx files, or when the user explicitly asks for the integrated TypeScript standards.

- Skill: `vaibtan/typescript-best-practices` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add vaibtan/typescript-best-practices`
- Raw SKILL.md: https://api.skillmd.com/api/skills/vaibtan/typescript-best-practices/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Vaibtan (https://skillmd.com/u/vaibtan)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/vaibtan/typescript-best-practices

---


# TypeScript best practices

Inspect the repository's TypeScript version, compiler settings, runtime, libraries, and established architecture before choosing a pattern. Apply these rules to the requested semantic surface. Do not turn a focused change into a repository-wide migration.

## Core rules

- Model meaningful variants with discriminated unions or another closed representation. Avoid bags of booleans and optional fields that admit contradictory states.
- Parse external input at the nearest owned boundary into named application or domain values. Keep transport, SDK, database, and framework types at adapters.
- Prefer construction that cannot create an invalid value. Add brands or refinements only when they prevent a realistic mix-up or partial operation.
- Preserve literal information with inference and `satisfies`. Derive from authoritative schemas or existing contracts before declaring parallel types.
- Avoid `any`, non-null assertions, and unchecked casts. When TypeScript cannot express a proven invariant, keep the exception narrow and explain the proof with a specific safety comment.
- Handle closed unions exhaustively so a new variant creates a compile error.
- Keep pure domain logic separate from effect sequencing and boundary translation. Add a service or adapter only when it owns real policy, authority, translation, or lifecycle.
- Prefer direct imports and cohesive modules. Avoid barrels, pass-through wrappers, vague utility files, and abstractions that merely rename another API.
- Test caller-visible behavior through real seams. Use module mocks only when the repository has no practical seam and the user accepts that tradeoff.
- Preserve observability and redact secrets at the boundary. Expected failures should use the repository's typed error convention when one exists.

Use [syntax and pattern examples](references/patterns.md) for a concrete TypeScript construct. Read the full [correct-by-construction standards](references/correct-by-construction.md) only for an explicit standards audit, a repository-wide standards decision, or a request for the complete dmmulroy guidance. The core rules above are enough for ordinary TypeScript architecture and implementation. Do not load the long reference as background context.

For Effect services, use `$effect-service-design`. For Cloudflare or Hono composition roots, use `$cloudflare-composition-root`. For a shared generic helper foundation, use `$prelude`. When the user asks to install executable enforcement, use `$install-anti-slop`; do not restate its rule catalog here.

