MODELING DATA · LESSON 8 OF 24
Nullability, unknown and safe error handling
Handle missing data without disabling the checker.
- null
- unknown
- optional chaining
- assertions
Your runnable checkpoint
Extract into a new practice folder. Each download includes complete source, package.json, tsconfig.json and an offline lesson. Use Node.js 22 or 24. Each checkpoint is independent.
Install with npm install. Run npm run check, then npm run build. Terminal lessons use npm start; browser lessons use npm run serve and http://127.0.0.1:4173.
1. Understand the concepts
With strictNullChecks, null and undefined remain distinct possibilities that must be handled. Optional chaining stops property access on nullish values. It does not validate the rest of a value or catch unrelated exceptions.
Nullish coalescing preserves useful falsy values such as 0 and an empty string. The || operator replaces all falsy values, which can accidentally erase meaningful data.
Type assertions such as value as User and non-null assertions such as element! do not validate, convert or create anything at runtime. Use them only when you have evidence the checker cannot express. Prefer checks when input can actually be missing.
Caught values can be anything thrown by JavaScript, including strings. Treat them as unknown and use instanceof Error before reading message. any would bypass these protections and let mistakes spread.
2. Build and run
These are complete files. Preserve the paths shown below, including the src directory. The package and compiler configuration are included at the end.
src/main.ts
type Profile = { address?: { city: string }; credits: number };
const profile: Profile = { credits: 0 };
console.log(profile.address?.city ?? "City missing");
console.log(profile.credits ?? 10);
function parse(text: string): unknown {
return JSON.parse(text);
}
try {
parse("not json");
} catch (error: unknown) {
console.log(error instanceof Error ? "Invalid JSON" : "Unknown failure");
}
package.json
{
"name": "edupoly-typescript-null-unknown-and-safe-errors",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"check": "tsc --noEmit",
"build": "tsc",
"start": "node dist/main.js"
},
"devDependencies": {
"typescript": "5.9.3"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": [
"ES2022",
"DOM"
],
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noEmitOnError": true,
"verbatimModuleSyntax": true,
"rootDir": "src",
"outDir": "dist",
"sourceMap": true,
"types": [],
"moduleDetection": "force"
},
"include": [
"src/**/*"
]
}
3. Trace the code and check the result
- Optional chaining produces undefined when address is absent.
- ?? preserves zero credits.
- JSON.parse has an unsafe library return type, so the wrapper intentionally exposes unknown.
Expected result
City missing
0
Invalid JSON4. Practice independently
Explain why JSON.parse(text) as Profile is unsafe.
Show the explanation
The assertion is erased. The input could be null or have the wrong fields. Parse to unknown, check its shape, and return Profile only after validation.
When something goes wrong
If tsc is missing, run npm install in the folder containing package.json. If the output looks old, rebuild before running. Read the first compiler diagnostic and check the indicated field or argument. For module errors, preserve the .js extensions in imports. Browser examples must run through the included local server, not directly as TypeScript files.
