instanceof, in and Equality Narrowing

instanceof

Example

instanceof narrows to a class type. It is the usual way to handle different error classes and built-ins like Date.

function toIso(value: Date | string | number): string {
  if (value instanceof Date) return value.toISOString();
  return new Date(value).toISOString();
}

console.log(toIso(new Date("2026-01-15T10:00:00Z")));
console.log(toIso("2026-03-01T00:00:00Z"));
console.log(toIso(0));

Output

2026-01-15T10:00:00.000Z
2026-03-01T00:00:00.000Z
1970-01-01T00:00:00.000Z

The in Operator

Example

"prop" in obj narrows to the union members that have that property.

type Admin = { name: string; permissions: string[] };
type Customer = { name: string; loyaltyPoints: number };

function summary(user: Admin | Customer): string {
  if ("permissions" in user) return user.name + " can " + user.permissions.join(", ");
  return user.name + " has " + user.loyaltyPoints + " points";
}

console.log(summary({ name: "Ops", permissions: ["refund", "ban"] }));
console.log(summary({ name: "Kavya", loyaltyPoints: 540 }));

Output

Ops can refund, ban
Kavya has 540 points

Equality Narrowing

Example

Comparing with === narrows both sides. x == null (double equals) checks for both null and undefined at once.

function compare(a: string | number, b: string | boolean): void {
  if (a === b) {
    console.log("both strings:", a.toUpperCase(), b.toLowerCase());
  } else {
    console.log("different:", a, b);
  }
}

function orDefault(x: number | null | undefined): number {
  return x == null ? 0 : x;
}

compare("upi", "upi");
compare(1, true);
console.log(orDefault(undefined), orDefault(null), orDefault(7));

Output

both strings: UPI upi
different: 1 true
0 0 7