Null Safety
Null Safety
Introduction
In this lesson, you'll learn about null safety in TypeScript. Coming from Java, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Java, you're familiar with null safety.
TypeScript has its own approach to null safety, which we'll explore step by step.
The TypeScript Way
Let's see how TypeScript handles this concept. Here's a typical example:
// TypeScript - optional chaining + nullish coalescing
function getString(): string | null { return null; }
const maybeStr: string | null = getString();
// Optional chaining (?.) — short-circuits on null/undefined
const upper = maybeStr?.toUpperCase(); // string | undefined
// Nullish coalescing (??) — fallback for null/undefined
const result = maybeStr?.toUpperCase() ?? "DEFAULT";
// Strict null checks (tsconfig: "strict": true)
// Without it, null can be assigned to anything — enable it!Comparing to Java
Here's how you might have written similar code in Java:
// Java - Optional to avoid NullPointerException
import java.util.Optional;
Optional<String> maybeStr = Optional.ofNullable(getString());
String result = maybeStr
.map(String::toUpperCase)
.filter(s -> s.length() > 3)
.orElse("DEFAULT");
// Without Optional — danger zone
String s = getString(); // might be null!
int len = s.length(); // NullPointerException!You may be used to different syntax or behavior.
Java's NullPointerException is infamous; TypeScript's optional chaining (?.) is a built-in language feature
You may be used to different syntax or behavior.
TypeScript union types (string | null) express nullability directly in the type; Java uses Optional<T>
You may be used to different syntax or behavior.
Optional chaining (?.) is shorter and more readable than Java's Optional.map()
You may be used to different syntax or behavior.
Nullish coalescing (??) is TypeScript's equivalent of Optional.orElse()
You may be used to different syntax or behavior.
TypeScript's strict mode enables strict null checks, preventing null/undefined from being assigned to non-nullable types
Step-by-Step Breakdown
1. Optional Chaining
The ?. operator short-circuits and returns undefined if the left side is null or undefined, instead of throwing.
// Java
if (user != null && user.getAddress() != null) {
String city = user.getAddress().getCity();
}// TypeScript
const city = user?.address?.city; // string | undefined
// Works for method calls too:
const upper = str?.toUpperCase();
// And array access:
const first = arr?.[0];2. Nullish Coalescing
The ?? operator returns the right side only when the left is null or undefined — not for other falsy values like 0 or ''.
String name = Optional.ofNullable(input).orElse("Anonymous");const name = input ?? "Anonymous";
// ?? vs || difference:
const count1 = 0 || 10; // 10 — || treats 0 as falsy
const count2 = 0 ?? 10; // 0 — ?? only triggers for null/undefined3. Non-Null Assertion
The ! postfix operator tells TypeScript you're certain a value is not null. Use sparingly.
// You know it's not null, TypeScript doesn't
const canvas = document.getElementById("myCanvas")!;
// Without ! TypeScript would say: HTMLElement | null
// Better alternative: check first
const el = document.getElementById("myCanvas");
if (el === null) throw new Error("Canvas not found");
el.style.display = "block"; // now TypeScript knows it's not null4. Strict Null Checks
Enable strict mode in tsconfig.json so TypeScript catches null/undefined errors at compile time.
// tsconfig.json
{ "compilerOptions": { "strict": true } }
// With strict on:
let name: string = null; // ERROR — null not assignable to string
// Must use union type:
let name: string | null = null; // OK
// Now TypeScript forces you to handle null:
function greet(name: string | null): string {
return `Hello, ${name ?? "stranger"}!`;
}Common Mistakes
When coming from Java, developers often make these mistakes:
- Java's NullPointerException is infamous; TypeScript's optional chaining (?.) is a built-in language feature
- TypeScript union types (string | null) express nullability directly in the type; Java uses Optional<T>
- Optional chaining (?.) is shorter and more readable than Java's Optional.map()
Key Takeaways
- Optional chaining (?.) replaces verbose null-check chains
- Nullish coalescing (??) is cleaner than Optional.orElse() for fallback values
- Union types (string | null) express nullability in the type system
- Enable strict mode in tsconfig.json to get compile-time null safety