Optional chaining reads through values that might be missing without throwing.

optional chaining The `?.` operator stops and returns `undefined` when the value on the left is missing.

Optional Chaining

hasContact
chaining.ts
Replay: real traced execution (multi-file project)
type Profile = {
    name: string;
    contact?: {
        email: string;
    };
};

const hasContact: boolean = true;
const profile: Profile = hasContact
    ? { name: "Ada", contact: { email: "ada@example.com" } }
    : { name: "Ada" };

const email: string | undefined = profile.contact?.email;
const message: string = email === undefined ? "no email" : email;

console.log(message);
type Profile = {
    name: string;
    contact?: {
        email: string;
    };
};

const hasContact: boolean = false;
const profile: Profile = hasContact
    ? { name: "Ada", contact: { email: "ada@example.com" } }
    : { name: "Ada" };

const email: string | undefined = profile.contact?.email;
const message: string = email === undefined ? "no email" : email;

console.log(message);
  1. hasContact ← true, profile ← [object Object], email ← ada@example.com

    5    };6};78const hasContact→ true: boolean = true;  //@hasContact=false9const profile→ [object Object]: Profile = hasContacttrue10    ? { name: "Ada", contact: { email: "ada@example.com" } }11    : { name: "Ada" };1213const email→ ada@example.com: string | undefined = profile.contact?.email→ ada@example.com;14const message→ ada@example.com: string = email→ ada@example.com === undefined ? "no email" : email;1516console.log(messageada@example.com);
    outputada@example.com
    values this step[object Object]profile.contact
  1. hasContact ← false, profile ← [object Object], email ← undefined

    5    };6};78const hasContact→ false: boolean = false;9const profile→ [object Object]: Profile = hasContactfalse10    ? { name: "Ada", contact: { email: "ada@example.com" } }11    : { name: "Ada" };1213const email→ undefined: string | undefined = profile.contact?.email→ undefined;14const message→ no email: string = email→ undefined === undefined ? "no email" : email;1516console.log(messageno email);
    outputno email
    values this stepundefinedprofile.contact