Null & Undefined

The Course
•
5 min read

JavaScript uses undefined for many missing values: an omitted optional argument, a missing property, or an unsuccessful array search. Null is often an explicit “no value” marker chosen by a program or data format. Under strictNullChecks, neither can be used wherever a string or number is expected.

A type such as string | null makes absence part of a contract. Handle it before using string methods. A direct comparison with null narrows that union. For both null and undefined, test each explicitly or use the nullish fallback operator you learned on Day 2.

Optional chaining, value?.trim(), skips the property access or call when value is null or undefined, producing undefined instead. It does not validate a wrong-but-present value. A number would not become valid text because you added a question mark. Combine optional chaining with a fallback only when absence has an intentional meaning.

Avoid the non-null assertion operator ! as a shortcut. It tells the checker to trust you without adding a runtime check. If the assumption is wrong, JavaScript can still fail. Prefer a real branch when the value may be absent.

Truthiness checks need care: if (minutes) excludes zero as well as absence. If zero means a valid empty plan, distinguish it from null. A good model does not accidentally treat useful data as missing.

Predict, check, then run

Before running, write down the output and explain which information the checker knows. Click Check types first, then Check & run.

Predict, then runTypeScript
function noteLabel(note: string | null): string {
  return note?.trim() ?? "No note";
}

console.log(noteLabel(null));
console.log(noteLabel("  Review  "));

const minutes: number | null = 0;

console.log(minutes ?? 25);

Enable JavaScript to edit and type-check this example.

Check your prediction
No note
Review
0

Read a real compiler error

Check before running. Identify the union member that cannot support trim.

Find and fix the type errorTypeScript
function label(note: string | null): string {
  return note.trim();
}

console.log(label(null));

Enable JavaScript to edit and type-check this example.

Check your diagnosis

The compiler reports that note is possibly null. Add a real null branch or use optional chaining with an intentional fallback. A non-null assertion would hide the warning without making null safe.

Check absence before using the present value

Null and undefined represent absence only when your contract says they do. Empty text and zero can still be present values. Use an explicit null check or a nullish fallback when that distinction matters.

Optional chaining safely stops an access when its receiver is nullish. It does not prove that a present string is nonblank, nor that a present number obeys a domain range. Preserve the difference between access safety and input validity.

Check absence before using the present value: traceTypeScript
function label(minutes: number | null): string {
  if (minutes === null) {
    return "Unknown";
  }

  return `${minutes} min`;
}

console.log(label(null));
console.log(label(0));

Enable JavaScript to edit and type-check this example.

Check your prediction
Unknown
0 min

The explicit null branch preserves zero. A condition like if(!minutes) would group zero with absence and change the public behavior.

Check absence before using the present value: contrastTypeScript
function note(value: string | null): string {
  return value?.trim() ?? "Missing";
}

console.log(note(null));
console.log(note("   ") === "");
console.log(note(" Review "));

Enable JavaScript to edit and type-check this example.

Check your prediction
Missing
true
Review

Whitespace becomes an empty string after trim. It is still not nullish, so the fallback does not run. Add a deliberate blank-text rule if the user experience requires one.

Try the rule on new inputs

Test null, empty text, spaces and ordinary text. Then decide which should display Missing. Implement that policy with a named intermediate value rather than assuming optional chaining also validates content.

Your turn

Exercise

Null & Undefined: practise

Write durationLabel(minutes: number | null): string. Null returns “Not planned”; zero returns “0 min”; other numbers use the same numeric label. Print the results for null, 0 and 25.

Your workspaceTypeScript
// Branch on absence, not truthiness.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

Zero is a value. Only null means no plan in this contract.

Hint 2: a first step

Compare minutes === null before constructing the label.

Show one solution
One possible solutionTypeScript
function durationLabel(minutes: number | null): string {
  if (minutes === null) {
    return "Not planned";
  }

  return `${minutes} min`;
}

console.log(durationLabel(null));
console.log(durationLabel(0));
console.log(durationLabel(25));

Enable JavaScript to edit and type-check this example.

Not planned
0 min
25 min

Explain the types at the function boundary and the runtime checks, if any. Compare your approach before copying this answer.

Change it and explain it

Allow undefined too and update the branch. Check all four cases. Then replace the explicit null condition with a truthiness check and explain the zero bug. Finally decide whether an empty note should display nothing or a fallback; make that rule explicit.

Was this article helpful?

Your response is saved on this device.