typescript-clean-codelisted
Install: claude install-skill mblauberg/provenant
# TypeScript clean code
Generic clean-code sense is assumed. Apply these TypeScript-specific rules. See
`references/typescript-patterns.md` for worked examples.
## Types
- **Make illegal states unrepresentable.** Prefer a discriminated union to
optional fields plus a flag.
- **Prefer `unknown` to `any`.** Narrow unknown input. Isolate and explain `any`
required by untyped interop, compatibility work or deliberate escape hatches.
- **Do not launder types with assertions.** Narrow with guards, `in`, `typeof`
or `instanceof`, or validate boundaries. Avoid `as` and `as unknown as`;
`as const` and `satisfies` are fine.
- **Enforce exhaustiveness with `never`.** Use `default: assertNever(x)` for
union switches.
- **Derive, do not duplicate.** Use `z.infer`, `keyof`, `typeof`, mapped types,
`Pick` or `Omit`; keep one source for each shape.
- Use `type` for unions/functions/mapped types and follow the repository's
established `type`/`interface` convention for object shapes.
- **Brand primitives that must not be interchanged**, such as `UserId` and
`OrderId`.
## tsconfig
- Target `strict`, `noUncheckedIndexedAccess` (indexed access can be
undefined), `exactOptionalPropertyTypes`,
`noImplicitOverride`, `noFallthroughCasesInSwitch` and
`useUnknownInCatchVariables`. For an existing codebase, stage flags with an
explicit migration and no silent public-type changes.
- Run `tsc --noEmit` in CI.
## Errors & null
- **`catch` binds `unknown`.** Narrow before acce