TS18048 — DedSec Project
TS18048 — possible undefined is a real missing-result branch Root cause TS18048 warns that a value is possibly undefined. Array.find returns the first matching element or undefined if there…
TS18048 — possible undefined is a real missing-result branch
Root cause
TS18048 warns that a value is possibly undefined. Array.find returns the first matching element or undefined if there is no match. Reading match.title immediately assumes all requested IDs exist, a premise that can fail on an empty array, a misspelled key, or a changed dataset.
Reliable fix
Check match === undefined before accessing its properties; TypeScript's control-flow analysis then narrows the type in the success branch. Throw a RangeError containing the missing ID rather than relying on a later TypeError. The test confirms the normal branch and an explicit absent-ID failure.
Verified TypeScript example
type RecordItem = {id: string; title: string};
function titleById(rows: RecordItem[], id: string): string {
const match = rows.find((row) => row.id === id);
if (match === undefined) throw new RangeError(`missing ID: ${id}`);
return match.title;
}
if (titleById([{id: 'A', title: 'Intro'}], 'A') !== 'Intro') throw Error();
try { titleById([], 'B'); throw Error('accepted missing ID'); }
catch (err) { if (!(err instanceof RangeError)) throw err; }
console.log('PASS TS18048');
Why it works
Optional chaining is useful if a missing result is acceptable and the return type reflects undefined, but a mandatory title lookup should not silently return an empty string. The non-null assertion operator (match!) compiles away and does not protect runtime. Do not confuse undefined from a missing lookup with a record whose title is an empty string; those require distinct policies.
Reproduction and build commands
Save as main.ts and run tsc --strict --target es2022 --module commonjs --outDir dist main.ts && node dist/main.js. Reproduce TS18048 in a separate file with const match = rows.find(...); console.log(match.id); compiled under --strict and a recent TypeScript version.
Diagnostics to practice
Replace find with Map.get(id) and identify the same undefined possibility. Design a union such as {ok:true,value:...}|{ok:false,error:...} instead of exceptions, then verify that callers narrow on ok before using value.
Reference: https://www.typescriptlang.org/docs/handbook/2/narrowing.html