Turn on and migrate to TypeScript's strict flags incrementally so the compiler catches real bugs. Use when configuring TypeScript strictness or tightening a loose codebase without a big-bang rewrite.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Amey-Thakur/AI-SKILLS --skill typescript-strictness --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Typescript Strictness?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/amey-thakur-typescript-strictness)More formats (shields.io, HTML) on the badges page.
---
name: typescript-strictness
description: Turn on and migrate to TypeScript's strict flags incrementally so the compiler catches real bugs. Use when configuring TypeScript strictness or tightening a loose codebase without a big-bang rewrite.
---
# TypeScript strictness
TypeScript's value is proportional to how strict you let it be. A loose
config with implicit `any` everywhere is JavaScript with extra syntax;
strict mode is where the compiler starts catching the null-deref and
type-mismatch bugs before they ship.
## Method
1. **Turn on `strict` for new projects, full stop.** It enables the
flags that matter together (`strictNullChecks`, `noImplicitAny`,
`strictFunctionTypes`, and the rest). Everything below is about
getting an existing loose codebase there without a rewrite.
2. **Migrate flag by flag, not all at once.** Enabling `strict` on a
large loose codebase surfaces thousands of errors and stalls. Turn on
one flag at a time, fix its errors, commit, repeat. `noImplicitAny`
and `strictNullChecks` are the two that find the most bugs and cause
the most work; schedule them deliberately.
3. **Add `strictNullChecks` early and take it seriously.** It separates
`T` from `T | null | undefined`, forcing you to handle absence at
every boundary. This is the single flag that prevents the most runtime
errors (the "cannot read property of undefined" class; see
null-handling). Expect it to touch a lot of code; the errors are real
bugs, not noise.
4. **Reach for `noUncheckedIndexedAccess` once strict is stable.** It
makes `arr[i]` return `T | undefined`, catching the off-by-one and
missing-key access that `strict` alone misses. High value, moderate
friction; add it after the baseline is clean.
5. **Contain the migration debt visibly.** Where you must defer fixes,
use explicit `// @ts-expect-error` with a reason (it fails the build
when the underlying issue is fixed, unlike `@ts-ignore` which rots
silently), and track the count downward. Never widen types to `any`
to silence errors; that spreads the looseness (see ts-api-types).
6. **Enforce in CI and forbid backsliding.** `tsc --noEmit` in CI (see
linting-setup); lint rules against `any` and non-null assertions
(`!`) except where justified. A strict config that any PR can quietly
loosen is not strict.
## Boundaries
- Strictness catches type bugs, not logic bugs; a fully-typed program can
still be wrong (see testing-strategy).
- Third-party libraries with weak or wrong types leak looseness in;
isolate them behind typed wrappers at the boundary rather than
weakening your own config (see ts-api-types).
- `strict` is a floor, not the ceiling: `noUncheckedIndexedAccess`,
`exactOptionalPropertyTypes`, and lint rules add more, each with its
own friction-to-value tradeoff to weigh per project.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!