agentleFS
motola10motola10/claude-code-base/.claude/skills/typescript-standards/SKILL.md

typescript-standards

Skill1 starsChanged 5 months agoMITView on GitHub

Cross-cutting language standards for TypeScript (tsconfig.json). Applied ALONGSIDE a runtime standard — nodejs-standards (backend) or react-standards/nextjs-standards (frontend). Covers compiler config (strict), type safety, modules, typescript-eslint, language patterns. Used by the review agents on any TypeScript code. Do NOT use as the sole standard — always pair with the runtime standard.

9 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

17 rules. 0 are common, 2 are distinctive, and 15 are very specific to this project.

  • 0

    Common

    Most of the 9 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 15

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Target: all TypeScript source — backend (Node/NestJS), frontend (React/Next.js), libraries, tooling.

    line 50
  2. Very specific:

    TS-CONFIG-5 (MUST): Commit a single source-of-truth tsconfig.json (extended per package in a monorepo via extends/project references).

    line 73
  3. Very specific:

    TS-TYPE-1 (MUST NOT): Use any to bypass the type system.

    line 83
  4. Very specific:

    TS-TYPE-2 (MUST NOT): Use unchecked type assertions (as Foo, as unknown as Foo) or the non-null assertion !

    line 86
  5. Very specific:

    Frontend / non-NestJS backends (SHOULD): Use Zod v4 (zod@^4) for runtime boundary validation — it infers TypeScript types from schemas …

    line 89
  6. Very specific:

    NestJS (SHOULD): Use class-validator + class-transformer (mandated by NODE-NEST-4 in nodejs.md) for DTO validation via decorators — do not …

    line 92
  7. Very specific:

    TS-TYPE-3 (SHOULD): Prefer the satisfies operator over an annotation when you want a value checked against a type *without* widening it …

    line 95
  8. Very specific:

    TS-TYPE-6 (SHOULD): Prefer unknown in catch (the useUnknownInCatchVariables default) and narrow.

    line 102
  9. Very specific:

    TS-TYPE-7 (SHOULD): Use readonly / Readonly<T> / readonly T[] for data that shouldn't be mutated, and immutable parameter types …

    line 105
  10. Very specific:

    TS-TYPE-8 (SHOULD NOT): Use numeric enums; prefer union string-literal types or as const objects (safer, erasable, better narrowing).

    line 107
  11. Very specific:

    TS-MOD-1 (MUST): Use ES modules (import/export).

    line 126
  12. Very specific:

    TS-MOD-2 (MUST): Use type-only imports/exports (import type { X }) for types, so they erase cleanly (required by verbatimModuleSyntax).

    line 128
  13. Distinctive:

    TS-MOD-3 (MUST NOT): Create circular module dependencies.

    line 131
  14. Distinctive:

    TS-MOD-4 (SHOULD): Prefer named exports over default exports for better refactoring, tree-shaking, and consistent import names.

    line 132
  15. Very specific:

    TS-LINT-3 (MUST): Treat these as errors: no-floating-promises (every promise awaited/handled — extends NODE-ASYNC-2), no-misused-promises, …

    line 144
  16. Very specific:

    TS-PAT-2 (SHOULD): Use interface for object/contract shapes that may be extended/implemented.

    line 155
  17. Very specific:

    TS-PAT-3 (SHOULD): Prefer precise utility types (Pick, Omit, Partial, Record, ReturnType, template-literal types) over restating shapes.

    line 158

“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

TypeScript Coding Standard (v1.0)

Status: Locked v1.0. TypeScript is a language, not a runtime, so this is a cross-cutting language standard: it is always applied alongside a runtime standard — nodejs.md (backend; NestJS already requires this doc) or the React/Next.js standards (frontend). Those runtime standards own runtime concerns (security, logging, dependency/supply-chain, test infrastructure, framework wiring); this document owns type safety, the compiler config, and language-level patterns, and does not repeat them.

On adoption this becomes .claude/skills/typescript-standards/SKILL.md + references/*.md.

Toolchain verified current as of 2026-06-13 (via Context7 + npm): TypeScript 6.0.x, typescript-eslint 8.x (flat config), tsx 4.x. Rules are written version-agnostically; these are reference points, not pins.


How to read this document

Constraint language (RFC 2119)

  • MUST / MUST NOT — hard requirement; a violation is a blocking issue.
  • SHOULD / SHOULD NOT — strong recommendation; deviate only with a written // Justification:.
  • MAY — optional.

Rule IDs

Stable TS-AREA-NUMBER (e.g. TS-TYPE-3). The reviewer MUST cite the rule ID. Never renumber.

Severity mapping

This document says…Reviewer severityGate
MUST/MUST NOT affecting type soundness / securityCriticalBlocks merge
MUST/MUST NOT elsewhereCritical / Warning (by impact)Blocks if it risks correctness
SHOULD without justificationWarningShould fix
MAY / stylisticSuggestionNice to have

Scope & Assumptions

  1. Target: all TypeScript source — backend (Node/NestJS), frontend (React/Next.js), libraries, tooling.
  2. Pairs with a runtime standard. Apply this together with nodejs.md or the frontend standards; on overlap, the stricter rule wins.
  3. Type-checking is mandatory and blocking — tsc --noEmit (or the build's type-check) MUST pass in CI.
  4. Custom overrides: the project's custom-standards skill overrides this document on conflict.

1. Compiler Configuration

  • TS-CONFIG-1 (MUST): Enable "strict": true in tsconfig.json (the master flag — turns on noImplicitAny, strictNullChecks, strictFunctionTypes, useUnknownInCatchVariables, alwaysStrict, etc.). New projects MUST NOT disable individual strict sub-flags without a written justification.
  • TS-CONFIG-2 (SHOULD): Enable the extra safety flags not included in strict: noUncheckedIndexedAccess (array/record access yields T | undefined), exactOptionalPropertyTypes, noImplicitOverride, noFallthroughCasesInSwitch, and noImplicitReturns.
  • TS-CONFIG-3 (MUST): Type errors are build failures — CI runs a type-check (tsc --noEmit or the framework's equivalent) and it MUST pass. Do not ship code with type errors suppressed wholesale.
  • TS-CONFIG-4 (SHOULD): Set a modern target/lib and explicit module/moduleResolution ("bundler" or "nodenext" as appropriate). Enable isolatedModules and verbatimModuleSyntax so the code is safe for single-file transpilers (esbuild/swc/tsx).
  • TS-CONFIG-5 (MUST): Commit a single source-of-truth tsconfig.json (extended per package in a monorepo via extends/project references). Tool and editor must read the same config.
  • TS-CONFIG-6 (SHOULD): Extend @tsconfig/strictest as the base ("extends": "@tsconfig/strictest/tsconfig.json"). This preset enables everything in TS-CONFIG-1 and TS-CONFIG-2 in one line and is maintained by the TypeScript team. Override individual flags only with a written // Justification:.

2. Type Safety

  • TS-TYPE-1 (MUST NOT): Use any to bypass the type system. Prefer unknown at untyped boundaries and narrow before use. An unavoidable any MUST be localized and carry // Justification:; enable @typescript-eslint/no-explicit-any.
  • TS-TYPE-2 (MUST NOT): Use unchecked type assertions (as Foo, as unknown as Foo) or the non-null assertion ! to silence the compiler. Narrow with runtime checks / type guards, or validate with a schema at external boundaries. as const and satisfies are fine.
    • Frontend / non-NestJS backends (SHOULD): Use Zod v4 (zod@^4) for runtime boundary validation — it infers TypeScript types from schemas (z.infer<typeof schema>), eliminating the need to maintain parallel type definitions.
    • NestJS (SHOULD): Use class-validator + class-transformer (mandated by NODE-NEST-4 in nodejs.md) for DTO validation via decorators — do not introduce a conflicting Zod layer on the same DTOs.
  • TS-TYPE-3 (SHOULD): Prefer the satisfies operator over an annotation when you want a value checked against a type without widening it (keeps literal/precise types).
  • TS-TYPE-4 (MUST): Annotate the return type of exported/public functions and module boundaries; rely on inference for local variables. Don't annotate what inference gets right.
  • TS-TYPE-5 (SHOULD): Model "one of N" states with discriminated unions, and make switch handling exhaustive via a never check in the default branch — so adding a variant becomes a compile error.
  • TS-TYPE-6 (SHOULD): Prefer unknown in catch (the useUnknownInCatchVariables default) and narrow; MUST NOT type a caught error as any. Throw and expect Error subclasses, never strings/objects.
  • TS-TYPE-7 (SHOULD): Use readonly / Readonly<T> / readonly T[] for data that shouldn't be mutated, and immutable parameter types (ReadonlyArray, Readonly) for inputs you don't own.
  • TS-TYPE-8 (SHOULD NOT): Use numeric enums; prefer union string-literal types or as const objects (safer, erasable, better narrowing). const enum is disallowed under isolatedModules.
// ✅ exhaustive discriminated union (TS-TYPE-5)
type Shape = { kind: "circle"; r: number } | { kind: "square"; size: number };
function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.r ** 2;
    case "square": return s.size ** 2;
    default: { const _exhaustive: never = s; return _exhaustive; } // compile error if a kind is added
  }
}

3. Modules & Imports

  • TS-MOD-1 (MUST): Use ES modules (import/export). MUST NOT use namespace/module constructs or require in new code.
  • TS-MOD-2 (MUST): Use type-only imports/exports (import type { X }) for types, so they erase cleanly (required by verbatimModuleSyntax). Enable @typescript-eslint/consistent-type-imports.
  • TS-MOD-3 (MUST NOT): Create circular module dependencies.
  • TS-MOD-4 (SHOULD): Prefer named exports over default exports for better refactoring, tree-shaking, and consistent import names.

4. Linting (typescript-eslint)

  • TS-LINT-1 (MUST): Lint with typescript-eslint in flat config (eslint.config.ts) on top of the runtime standard's ESLint base, and it MUST pass in CI. Formatting is delegated to Prettier (per the runtime standard) — type-aware lint here covers correctness, not style.
  • TS-LINT-2 (MUST): Enable the type-checked ruleset (recommendedTypeChecked / strictTypeChecked) so rules that need type information run.
  • TS-LINT-3 (MUST): Treat these as errors: no-floating-promises (every promise awaited/handled — extends NODE-ASYNC-2), no-misused-promises, no-explicit-any, and the no-unsafe-* family (no-unsafe-assignment/return/argument/member-access/call).

5. Language Patterns & Readability

  • TS-PAT-1 (SHOULD): Naming — camelCase for variables/functions, PascalCase for types, interfaces, classes, and enums-replacement unions, UPPER_SNAKE_CASE for true constants. Don't prefix interfaces with I.
  • TS-PAT-2 (SHOULD): Use interface for object/contract shapes that may be extended/implemented; use type for unions, tuples, mapped/conditional types, and function types. Be consistent within a module.
  • TS-PAT-3 (SHOULD): Prefer precise utility types (Pick, Omit, Partial, Record, ReturnType, template-literal types) over restating shapes; derive types from a single source of truth rather than duplicating them.
  • TS-PAT-4 (SHOULD NOT): Over-engineer types — deeply nested conditional/recursive generics that hurt readability and compile time are a smell. Favor the simplest type that is sound.

Resolved Decisions (v1.0)

#QuestionDecisionRule
1noUncheckedIndexedAccess + exactOptionalPropertyTypes — MUST or SHOULD?SHOULD — high friction; TypeScript team intentionally excluded them from strictTS-CONFIG-2
2Validation libraryZod v4 for frontend/non-Nest; class-validator for NestJS (per NODE-NEST-4)TS-TYPE-2
3tsconfig baseExtend @tsconfig/strictest — covers all §1 flags in one presetTS-CONFIG-6
4DepthLean — no bundled reference configs; keep standard self-contained—

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.