Question

How to Check for null and undefined in TypeScript

typescriptnull-check

Question

In TypeScript, what is the correct way to check whether a value is either null or undefined?

Because TypeScript is strongly typed, using a loose conditional such as if (value) {} does not seem precise enough when the goal is specifically to detect null and undefined.

Is there a dedicated TypeScript feature, built-in function, or syntax shortcut for checking both cases safely and clearly?

Short Answer

By the end of this page, you will understand how to check for null and undefined in TypeScript, when to use value == null, when to use strict comparisons, and why if (value) is often the wrong tool for this job. You will also see how these checks affect type narrowing in real code.

Concept

In TypeScript, null and undefined are two distinct values.

  • undefined usually means a value was not provided or has not been assigned.
  • null usually means a value was intentionally set to “no value”.

Even though they are different, developers often need to treat them the same way: “this value is missing”.

That is why checks for both null and undefined are very common.

Why if (value) is not enough

A truthy check like this:

if (value) {
  // ...
}

does not only exclude null and undefined. It also excludes other falsy values such as:

  • 0
  • ""
  • false
  • NaN

So if 0 or an empty string are valid values in your program, if (value) can give the wrong result.

Common ways to check

1. Check both explicitly

if (value !== null && value !== undefined) {
  // value is present
}

This is the most explicit and beginner-friendly approach.

2. Use value == null

if (value == null) {
  // value is either null or undefined
}

This is one of the few places where loose equality is commonly and intentionally used in JavaScript and TypeScript.

  • value == null means value is null or undefined
  • value != null means value is neither null nor undefined

This works because JavaScript defines null == undefined as true, while other values do not match.

Why this matters in TypeScript

TypeScript uses these checks for type narrowing. That means after a successful null/undefined check, TypeScript can often treat the value as a non-null type.

Example:

function printLength(text: string | null | undefined) {
  if (text != null) {
    console.log(text.length);
  }
}

Inside the if block, TypeScript knows text is a string.

This makes your code safer and reduces runtime errors such as:

Cannot read properties of null

Mental Model

Think of a variable as a mailbox.

  • undefined means the mailbox was never given a letter.
  • null means someone deliberately placed a note saying, “there is no letter.”

In both cases, you still do not have a real message to read.

A check like value == null is like asking:

“Is the mailbox effectively empty, whether nothing was ever delivered or it was explicitly marked empty?”

A truthy check like if (value) asks a different question:

“Does this value look usable in a general boolean sense?”

That second question is broader, so it may reject values that are perfectly valid, such as 0 or "".

Take Quiz

Syntax and Examples

Core syntax

Check for both null and undefined

if (value == null) {
  // value is null or undefined
}
if (value != null) {
  // value is neither null nor undefined
}

Explicit strict comparison

if (value === null || value === undefined) {
  // missing value
}
if (value !== null && value !== undefined) {
  // present value
}

Example 1: Safe string handling

function greet(name: string | null | undefined) {
  if (name == null) {
    console.log("Hello, guest!");
    return;
  }

  console.log(`Hello, ${name}!`);
}

Here, name == null covers both missing cases.

Example 2: Why truthy checks can fail

function printCount(count: number | null | undefined) {
  if (count) {
    console.log(`Count is ${count}`);
  } else {
    console.log("Count is missing");
  }
}

printCount(0);

This prints the wrong result because 0 is falsy.

A better version is:

function printCount(count: number | null | undefined) {
  if (count != null) {
    console.log(`Count is ${count}`);
  } else {
    console.log("Count is missing");
  }
}

Now 0 is handled correctly.

Example 3: Optional values from APIs

type User = {
  email?: string | null;
};

function showEmail(user: User) {
  if (user.email != null) {
    console.log(user.email.toLowerCase());
  } else {
    console.log("No email available");
  }
}

This is common when API fields may be absent or explicitly null.

Step by Step Execution

Consider this example:

function printMessage(message: string | null | undefined) {
  if (message != null) {
    console.log(message.toUpperCase());
  } else {
    console.log("No message");
  }
}

printMessage("hello");
printMessage(null);
printMessage(undefined);

Step by step

Call 1: printMessage("hello")

  • message receives the string "hello"
  • The condition message != null is checked
  • "hello" is neither null nor undefined
  • The condition is true
  • TypeScript narrows message to string inside the block
  • message.toUpperCase() runs and prints HELLO

Call 2: printMessage(null)

  • message receives null
  • The condition message != null is checked
  • Since message is null, the condition is false
  • The else block runs
  • It prints No message

Call 3: printMessage(undefined)

  • message receives undefined
  • The condition message != null is checked
  • Since message is undefined, the condition is false
  • The else block runs
  • It prints No message

Key result

The single check message != null safely handles both missing-value cases while still allowing valid values like empty strings.

Real World Use Cases

Where this is used

Form input handling

A field may be missing, intentionally blank, or contain a real value.

function validateAge(age: number | null | undefined) {
  if (age == null) {
    return "Age is required";
  }

  return age >= 18 ? "Adult" : "Minor";
}

API responses

External APIs often return optional or nullable properties.

type Product = {
  price?: number | null;
};

function formatPrice(product: Product) {
  if (product.price == null) {
    return "Price unavailable";
  }

  return `$${product.price.toFixed(2)}`;
}

Configuration values

Apps often read environment values that may be absent.

function getPort(port: number | undefined) {
  return port != null ? port : 3000;
}

Database fields

A database column may allow NULL, while missing application data may show up as undefined.

function canSendReminder(lastLogin: Date | null | undefined) {
  if (lastLogin == null) {
    return false;
  }

  return true;
}
Take Quiz

Real Codebase Usage

In real projects, developers usually combine null/undefined checks with a few common patterns.

Guard clauses

A guard clause exits early when required data is missing.

function sendEmail(address: string | null | undefined) {
  if (address == null) {
    throw new Error("Email address is required");
  }

  console.log(`Sending email to ${address}`);
}

This keeps the rest of the function simpler.

Default values

If a value is missing, provide a fallback.

function getDisplayName(name: string | null | undefined) {
  return name ?? "Anonymous";
}

The ?? operator only falls back for null and undefined, not for "" or 0.

Validation before processing

function saveScore(score: number | null | undefined) {
  if (score == null) {
    return { success: false, error: "Score is missing" };
  }

  return { success: true, value: score };
}

Optional chaining with null checks

type Profile = {
  contact?: {
    email?: string | null;
  };
};

function getEmail(profile: Profile) {
  return profile.contact?.email ?? "No email";
}

Filtering out nullish values

This is common when cleaning data.

const values: Array<number | null | undefined> = [1, null, 2, undefined, 3];
const presentValues = values.filter((value) => value != null);

In many codebases, this style is preferred because it is short, readable, and expresses exactly what “present” means.

Common Mistakes

1. Using if (value) when 0, false, or "" are valid

Broken example:

function showPrice(price: number | null | undefined) {
  if (price) {
    console.log(price);
  } else {
    console.log("Missing price");
  }
}

If price is 0, this incorrectly says it is missing.

Use this instead:

if (price != null) {
  console.log(price);
}

2. Forgetting that null and undefined are different values

Broken example:

if (value === null) {
  // only catches null, not undefined
}

If you need both, use:

if (value == null) {
  // catches both
}

3. Avoiding == null because all loose equality seems bad

Usually, == is discouraged. But value == null is a well-known exception because it intentionally matches exactly two values:

  • null
  • undefined

It does not match 0, false, or "".

4. Using || instead of ?? for defaults

Broken example:

const count = input || 10;

If input is 0, this wrongly becomes 10.

Use:

const count = input ?? 10;

5. Assuming TypeScript always narrows after unclear checks

TypeScript narrows best when your condition clearly expresses nullish checking.

Good:

if (value != null) {
  value.toString();
}

Less precise for intent:

if (value) {
  value.toString();
}

The second check mixes nullish checking with truthiness.

Comparisons

ApproachChecks for nullChecks for undefinedRejects 0/""/falseBest use
if (value)Yes indirectlyYes indirectlyYesGeneral truthy/falsy logic
value == nullYesYesNoCheck for missing value
value != nullExcludes nullExcludes undefinedNoCheck that value is present
value === nullYesNoNoOnly when null specifically matters
value === undefinedNoYesNoOnly when undefined specifically matters
value !== null && value !== undefinedExcludes nullExcludes undefinedNoMost explicit form
value ?? fallbackHandles nullHandles undefinedNoSet default values
`valuefallback`Handles many falsy valuesHandles many falsy values

Rule of thumb

  • Use value == null when you want to know if a value is missing.
  • Use value != null when you want to know if a value is present.
  • Use ?? when you want a default only for null or undefined.
  • Avoid if (value) if 0, false, or "" should be allowed.
Take Quiz

Cheat Sheet

Quick reference

Check for missing value

value == null

True when value is:

  • null
  • undefined

Check for present value

value != null

True when value is not:

  • null
  • undefined

Explicit strict version

value === null || value === undefined
value !== null && value !== undefined

Use a default only for nullish values

const result = value ?? fallback;

Avoid this when valid values can be falsy

if (value) {
  // may reject 0, false, ""
}

Best practices

  • Prefer value != null for a short present-value check.
  • Prefer strict comparisons when you want maximum explicitness.
  • Use ?? instead of || for null/undefined defaults.
  • Let TypeScript narrow types after nullish checks.

Edge case reminder

null == undefined // true
null === undefined // false

FAQ

Is value == null valid in TypeScript?

Yes. It is a common and intentional way to check whether a value is either null or undefined.

Should I use if (value) to check for null and undefined?

Usually no. It also treats 0, false, "", and NaN as false, which may not match your intent.

What is the difference between null and undefined in TypeScript?

undefined usually means a value was not assigned or provided. null usually means the absence of a value was intentional.

Is == null better than === null || === undefined?

They are both correct. == null is shorter, while the strict version is more explicit.

Does TypeScript narrow types after value != null?

Yes. In many cases, TypeScript understands that the value is no longer null or undefined inside that branch.

Should I use || or ?? for fallback values?

Use ?? if you only want to replace null or undefined. Use || only when you want all falsy values to trigger the fallback.

Is there a built-in TypeScript function for null and undefined checks?

There is no special dedicated built-in function for this. Developers typically use value == null, value != null, strict comparisons, or ??.

Take Quiz

Mini Project

Description

Build a small TypeScript utility for displaying profile information where some fields may be missing. This project demonstrates how to correctly check for null and undefined without accidentally rejecting valid values like 0 or an empty string.

Goal

Create a function that safely formats user profile data and provides sensible fallbacks only when values are actually missing.

Requirements

  1. Define a UserProfile type with nullable or optional fields.
  2. Create a function that prints a user's name, age, and bio.
  3. Treat null and undefined as missing values.
  4. Do not treat 0 as missing for age.
  5. Use ?? or != null where appropriate.
Take Quiz

Keep learning

Related questions

View more