The in operator checks whether an object has a property and narrows the union.

In Operator Guard

in_guard.ts
type EmailContact = {
    address: string;
};

type SmsContact = {
    phone: string;
};

function routeContact(contact: EmailContact | SmsContact): string {
    if ("address" in contact) {
        return `email:${contact.address}`;
    }
    return `sms:${contact.phone}`;
}

const channel: string = ;
const contact: EmailContact | SmsContact =
    channel === "email"
        ? { address: "ada@example.com" }
        : { phone: "555-0100" };

console.log(routeContact(contact));
type EmailContact = {
    address: string;
};

type SmsContact = {
    phone: string;
};

function routeContact(contact: EmailContact | SmsContact): string {
    if ("address" in contact) {
        return `email:${contact.address}`;
    }
    return `sms:${contact.phone}`;
}

const channel: string = ;
const contact: EmailContact | SmsContact =
    channel === "email"
        ? { address: "ada@example.com" }
        : { phone: "555-0100" };

console.log(routeContact(contact));
property guard `"address" in value` narrows a union to the object shape that owns that property.