Q11 of 38 · TypeScript
How does TypeScript handle `null` and `undefined`, and what does `strictNullChecks` do?
Short answer
Short answer: With `strictNullChecks: true`, `null` and `undefined` are not assignable to other types — they must be explicitly included in a union (`string | null`). Without it, any value can be null, silently. Strict mode enables this flag by default, making null-safety enforced at compile time.
Detail
By default (without strictNullChecks), TypeScript allows null and undefined to be assigned to any type. This matches JavaScript's permissive behaviour but misses a whole class of runtime errors.
strictNullChecks: true: Null and undefined are their own distinct types. You cannot assign null to string — you must use string | null. Before using a nullable value, you must narrow it (if check, optional chaining, non-null assertion).
Narrowing null: TypeScript understands if (x !== null), if (x != null) (both null and undefined), optional chaining (x?.y), and nullish coalescing (x ?? default).
Non-null assertion (!): x! tells TypeScript "I know this is not null/undefined". It suppresses the null error but throws no runtime check — if you're wrong, you get a runtime error. Use sparingly and only when you have external knowledge the compiler lacks.
Strict mode: Enabling "strict": true in tsconfig turns on strictNullChecks (plus several other checks). This is the recommended baseline for all TypeScript projects including test suites.
In test automation: Playwright element handles (Locator | null), optional API response fields, and database query results all benefit from null-safe handling.
// EXAMPLE
// Without strictNullChecks (not recommended)
let name: string = null; // allowed! silent runtime bomb
// With strictNullChecks: true
let name2: string = null; // Error!
let name3: string | null = null; // ok — explicit
// Narrowing
function getLength(s: string | null): number {
if (s === null) return 0;
return s.length; // TypeScript knows s is string here
}
// Optional chaining
const city = user?.address?.city; // undefined if any step is null
// Non-null assertion — use with care
const el = document.getElementById("btn")!; // "I know it exists"
el.click(); // no null check — runtime error if element missing
// API response with optional fields
interface ApiUser {
id: number;
deletedAt: string | null; // null = not deleted
}
function isDeleted(u: ApiUser): boolean {
return u.deletedAt !== null;
}