in Operator Guard
In this page:
Basic in Operator Guard
The in operator has the form property in object, and when different object types in a union have different property names, checking for one of those properties lets TypeScript narrow the value to whichever branch of the union actually has it.
Example: Basic in Operator Guard
type Cat = { meow: () => void };
type Dog = { bark: () => void };
function speak(pet: Cat | Dog) {
if ("meow" in pet) {
pet.meow();
} else {
pet.bark();
}
}
speak({ meow: () => console.log("Meow") });
in Operator with Object Properties
The in operator is useful when object types share some properties but each has additional properties the others lack, since checking for the distinguishing property is often simpler than relying on a dedicated discriminant field.
Example: in Operator with Object Properties
type Circle = { radius: number };
type Square = { side: number };
function area(shape: Circle | Square): number {
if ("radius" in shape) {
return 3.14 * shape.radius ** 2;
}
return shape.side ** 2;
}
console.log(area({ side: 4 }));
in Operator with Methods
The property checked by in does not have to hold data; it can also be a method name, which is useful for narrowing between interfaces that are shaped like capabilities (for example, checking for a fetchData method) rather than plain data fields.
Example: in Operator with Methods
type Flyer = { fly: () => void };
type Swimmer = { swim: () => void };
function move(entity: Flyer | Swimmer) {
if ("fly" in entity) {
entity.fly();
} else {
entity.swim();
}
}
move({ fly: () => console.log("Flying") });
in Operator with Multiple Union Members
The in operator can be used repeatedly when a union contains several object types, checking one candidate property per branch until the code has narrowed the value down to a single specific shape.
Example: in Operator with Multiple Union Members
type A = { a: string };
type B = { b: string };
type C = { c: string };
function handle(value: A | B | C) {
if ("a" in value) console.log("A:", value.a);
else if ("b" in value) console.log("B:", value.b);
else console.log("C:", value.c);
}
handle({ c: "hi" });
in Operator with Unknown Values
The in operator can also help narrow unknown values, but the value must first be confirmed to be an object (for example with typeof value === object && value !== null) before TypeScript will allow a property check on it.
Example: in Operator with Unknown Values
function printName(value: unknown) {
if (typeof value === "object" && value !== null && "name" in value) {
console.log((value as { name: string }).name);
}
}
printName({ name: "Ravi" });
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: