Back to the blog
TypeScriptยท Feb 03, 2026ยท 7 min read

Turning on every strict TypeScript flag - was it worth it?

noUncheckedIndexedAccess, exactOptionalPropertyTypes, and friends. The bugs we caught, the noise we tolerated, and what we'd do again.

#typescript#tooling#dx

`strict: true` is table stakes at this point. The interesting question is what happens when you go further - the flags that aren't bundled into `strict` and that most teams leave off because they're noisy. We turned them all on for one quarter and tracked what each one actually caught.

noUncheckedIndexedAccess: the highest signal-to-noise flag we tried

Without this flag, `arr[i]` is typed as `T`, even though it's really `T | undefined` at runtime if `i` is out of bounds. This flag makes TypeScript honest about that. It immediately surfaced a handful of real bugs - places where we destructured array results assuming they always existed - and the fix pattern (explicit checks, or `.at()` with a guard) made the code more honest about its own assumptions. This is the one flag we'd recommend to literally every team, no exceptions.

// Before: typed as string, actually undefined if empty
const first = items[0];
first.toUpperCase(); // crashes at runtime, no warning at compile time

// After noUncheckedIndexedAccess:
const first = items[0]; // typed as string | undefined
if (!first) throw new Error('Expected at least one item');
first.toUpperCase(); // safe

exactOptionalPropertyTypes: high cost, narrow benefit

This flag distinguishes between a property that's missing and a property that's explicitly set to `undefined`. It's technically correct and it did catch one real bug in how we handled partial form updates, but it required touching dozens of type definitions across the codebase for a single legitimate catch. We kept it, but we wouldn't blame a team for skipping this one - the ROI is much lower than `noUncheckedIndexedAccess`.

noPropertyAccessFromIndexSignature: good for catching typos, annoying for dynamic data

This one forces bracket notation (`obj['key']`) instead of dot notation (`obj.key`) for properties that come from an index signature, which is a good typo-catcher for config-object-shaped data but actively annoying for anything that legitimately has dynamic keys, like a translations dictionary. We scoped it off for a few specific modules instead of applying it globally.

What we'd tell a team starting today

  • Turn on noUncheckedIndexedAccess immediately - it's the best bug-to-effort ratio of any flag we tested.
  • Add exactOptionalPropertyTypes only if you have time budgeted for the type-definition cleanup it requires.
  • Scope noPropertyAccessFromIndexSignature per-module rather than globally if your codebase has legitimate dynamic-key objects.
  • Whatever you enable, do it on a dedicated branch with CI green before merging - the diff from flipping a strictness flag touches far more files than you'd expect.

Written by Appesto Engineering.