Bug-Catching TS Flags: noUncheckedIndexedAccess & exactOptionalPropertyTypes
Two TypeScript options that catch real production bugs: safer indexing and optional properties that behave like you think.
On this page
What you’ll learn
- Why
obj[key]is usually unsafe - What
noUncheckedIndexedAccesschanges and the trade-offs - Why
exactOptionalPropertyTypesprevents subtle API bugs
30‑second interview answer
noUncheckedIndexedAccess makes indexed access return T | undefined because the key might not exist. This catches real crashes in maps and object lookups. exactOptionalPropertyTypes makes optional properties truly “possibly missing”, not “present but undefined”, which improves correctness for APIs and patch objects. Both flags increase safety but may require stricter checks.
1) noUncheckedIndexedAccess
The bug
const scores: Record<string, number> = {
alice: 10
};
function doubleScore(name: string) {
return scores[name] * 2;
}
// name = "bob" → scores["bob"] is undefined → NaNWithout the flag, TS assumes scores[name] is number.
With noUncheckedIndexedAccess
scores[name] becomes number | undefined, forcing you to handle the missing case:
function doubleScore(name: string) {
const score = scores[name];
if (score === undefined) return 0;
return score * 2;
}Trade-off
- More
undefinedhandling - But fewer runtime surprises (especially in large apps)
2) exactOptionalPropertyTypes
The confusion
Optional property x?: string is not always the same as x: string | undefined.
In real APIs, “missing” often means “don’t change it”, while undefined might mean “clear it”.
Example: patch object
type PatchUser = {
name?: string;
};
function applyPatch(patch: PatchUser) {
// should treat missing as "no change"
}With exactOptionalPropertyTypes, TS becomes stricter:
- You can omit
name - But you can’t freely assign
name: undefinedunless your type explicitly allows it
This prevents accidentally sending { name: undefined } over the wire.
Fix when you actually want undefined
Be explicit:
type PatchUser = {
name?: string | undefined;
};When to enable these flags
Enable when:
- You have lots of map/dictionary lookups
- You build patch/update APIs
- You want TS to behave closer to runtime truth
Be careful when:
- You’re migrating a huge legacy codebase (do it incrementally)
Production rule of thumb
noUncheckedIndexedAccessis worth it for correctness in serious apps.exactOptionalPropertyTypesis excellent for API clients and patch semantics.
Interview questions
-
Q: Why does
noUncheckedIndexedAccessexist?- A: Because indexing can fail at runtime; the type should reflect that possibility.
-
Q: Why is optional not the same as
| undefined?- A: Optional means “may be missing entirely”, which is important for API semantics.
Quick recap
- Indexing is unsafe by default; the flag forces you to handle it.
- Optional properties have subtle meaning; exact optional types make it explicit.
- Both flags catch real bugs.
Looking for structured, offline interview prep?
Free online lessons • Portable Amazon Kindle / Paperback
Frontend Interview Guide (2025 Edition)
By Rajesh Dhiman
Comprehensive preparation covering React internals, Web Performance, CSS architecture, and system design questions.
JavaScript Interview Guide
By Rajesh Dhiman
Deep dive into the Event Loop, microtask draining, closures, prototypal inheritance, and asynchronous execution patterns.
Note: All lessons on Frontend Interview remain completely free to read online. As an Amazon Associate, we may earn from qualifying purchases.
Written by Rajesh Dhiman
Authored by Rajesh Dhiman and engineered at Eunix Tech. Focused on deep-dive frontend engineering, JavaScript runtime internals, React architecture, and web performance.