null

Names the intentional-absence value as its own type once strictNullChecks is enabled.

Signature
let value: string | null = null;
  • Added in TypeScript 2.0

Errors

With strictNullChecks on, reading a property of a possibly-null value is a compile error: "'value' is possibly 'null'."

Changelog

  • PHP 2.0null and undefined became usable as type names in any mode, and strictNullChecks was added: null is then assignable only to null and any.
  • PHP 3.7Optional chaining (?.) and nullish coalescing (??) added, short-circuiting on both null and undefined.
  • PHP 4.9unlisted

null is JavaScript's value for deliberate absence, and TypeScript gives it a type of the same name. Whether that type does anything depends entirely on one compiler option.

With strictNullChecks off

null is in the domain of every type. let name: string = null compiles, and so does reading a property off a value that is null at runtime. The type string is a lie about what can arrive.

With strictNullChecks on

null is only assignable to null and any. To allow it you must say so — string | null — and to use such a value you must first eliminate the null branch with a comparison, a truthiness check, ?., or ??. This is the setting that converts a whole class of runtime crashes into compile errors, and it is on under strict.

Choosing between null and undefined

Both mean "no value". Convention: undefined for something never set, null for something explicitly cleared — for example a database column that is present but empty. Pick one per codebase and stay with it; ?? and ?. treat them identically anyway.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Modelling a nullable database column that is present in the row but has no value
  • Returning null from a lookup to distinguish "searched and found nothing" from "never ran"
  • Turning a possible crash into a compile error by enabling strictNullChecks on a legacy file

Frequently asked questions

How do I fix "Object is possibly 'null'" in TypeScript?

Narrow the value before using it — check `x !== null`, use a truthiness `if (x)`, or reach through with optional chaining `x?.prop`. Supply a fallback with `x ?? fallback` when you need a value either way. The non-null assertion `x!` also compiles, but it only silences the checker; use it when you can prove the value is set and the checker cannot.

Should I use null or undefined in TypeScript?

Pick one convention per codebase. `undefined` is what JavaScript produces for missing properties, unset variables, and omitted arguments, so it is the lower-friction default; `null` reads better for a value that was deliberately cleared, such as a nullable database column. `??` and `?.` treat both identically, so the choice is about consistency, not behaviour.

What does strictNullChecks actually change?

It removes `null` and `undefined` from the domain of every other type. With it off, `let s: string = null` compiles and nullable values are invisible; with it on, you must write `string | null` to permit null and narrow before use. It is enabled by `strict` and is the single highest-value flag for preventing "cannot read property of null" crashes.

More examples

Narrowing null away

The `while (current !== null)` guard is what lets `current.name` compile — without it tsc reports "'current' is possibly 'null'". The last two lines show optional chaining returning `undefined` rather than throwing when the link is null, which is why `?.` result types always include `undefined` even for a `| null` input.

Example · typescript
interface User { name: string; manager: User | null }

const alice: User = { name: "Alice", manager: null };
const bob: User = { name: "Bob", manager: alice };

function chain(user: User): string[] {
  const names = [user.name];
  let current = user.manager;
  while (current !== null) {   // the guard that makes .name legal below
    names.push(current.name);
    current = current.manager;
  }
  return names;
}

console.log(chain(bob));            // [ 'Bob', 'Alice' ]
console.log(chain(alice));          // [ 'Alice' ]
console.log(bob.manager?.name);     // 'Alice'
console.log(alice.manager?.name);   // undefined — ?. short-circuits on null

typeof "object" is not a null check

Prints `2`, `-1`, `-1`, `object`. Without `value !== null`, `typeof value === "object"` would let `null` into `Object.keys` and throw at runtime — TypeScript catches this only under `strictNullChecks`. The final line shows `!` removing `null` from the static type while the value is still null at runtime.

Example · typescript
function keyCount(value: unknown): number {
  // Missing the null check here would be a bug: typeof null === "object"
  if (typeof value === "object" && value !== null) {
    return Object.keys(value).length;
  }
  return -1;
}

console.log(keyCount({ a: 1, b: 2 })); // 2
console.log(keyCount(null));           // -1
console.log(keyCount("text"));         // -1

// The non-null assertion silences the checker without checking anything:
const maybe: string | null = null;
console.log(typeof maybe!);            // "object" — the ! proved nothing

Discussion

  • Be the first to comment on this lesson.