TypeScript Index Access With noUncheckedIndexedAccess
noUncheckedIndexedAccess is a compiler flag that adds undefined to the type of every index read. Code written for the flag checks each read before use, because any slot may be empty.
noUncheckedIndexedAccess makes an array read number | undefined
The first read is present and prints after its check. The read past the end of the array is undefined, and the comparison proves it.
const scores: number[] = [90, 85, 70];
const first = scores[0];
if (first !== undefined) {
console.log(first);
} else {
console.log('empty slot');
}
const beyond = scores[5];
console.log(beyond === undefined);noUncheckedIndexedAccess refuses an unchecked read
An unguarded style stores an index read straight into a number variable. Under the flag the checker refuses the store, because the read may be undefined.
const scores: number[] = [90, 85, 70];
const first: number = scores[0];
console.log(first);noUncheckedIndexedAccess hardens a record lookup
Prices live in a Record keyed by product name. The lookup gains undefined under the flag, and the hardened code prints a fallback line for a missing key.
const prices: Record<string, number> = { pen: 25, book: 120 };
function showPrice(itemName: string): void {
const price = prices[itemName];
if (price !== undefined) {
console.log(itemName + ': ' + price);
} else {
console.log(itemName + ': not stocked');
}
}
showPrice('pen');
showPrice('lamp');noUncheckedIndexedAccess accepts a nullish fallback
The ?? operator replaces an undefined read with a default in one expression. The present slot and the empty slot both print a plain number.
const levels: number[] = [3, 1, 4];
const picked = levels[1] ?? 0;
const missing = levels[9] ?? 0;
console.log(picked);
console.log(missing);Example
const cartItems: string[] = ['pen', 'book', 'lamp'];
const counts: Record<string, number> = { pen: 2, book: 1 };
const firstItem = cartItems[0];
if (firstItem !== undefined) {
console.log(firstItem);
}
const penCount = counts['pen'] ?? 0;
console.log(penCount);
const lampCount = counts['lamp'] ?? 0;
console.log(lampCount);
console.log(cartItems.length);Key points
- The flag changes index reads on arrays and records, so a read from a number array has type number or undefined.
- A value read from a Record by a string key also gains undefined under the flag.
- Checking a read against undefined narrows it to the plain element type inside the check.
- A nullish fallback with ?? supplies a value for the empty case in one line.
- Reads in the intermediate course were already guarded, and the flag turns that habit into a requirement.
In this example, every index read is either checked against undefined or given a nullish fallback, so the program compiles under the flag and prints the guarded values in order.
Note
The flag changes types only, and the emitted JavaScript is the same with the flag on or off.
Try it Yourself
Edit the code, then press Run.
Running is simulated · TypeScript Playground
Exercise
Under noUncheckedIndexedAccess, what is the type of an index read from a number array?