How can I combine destructuring assignment and optional chaining?

danvk picture danvk · Nov 14, 2019 · Viewed 8.9k times · Source

I have a TypeScript interface with some optional fields and a variable of that type:

interface Foo {
    config?: {
        longFieldName?: string;
    }
}

declare let f: Foo;

I'd like to put longFieldName in a variable of the same name.

If config weren't optional, I'd use destructuring assignment to do this without repeating longFieldName. But it is, so I get a type error:

const { longFieldName } = f.config;
     // ~~~~~~~~~~~~~  Property 'longFieldName' does not exist on type '{ longFieldName?: string | undefined; } | undefined'.

I can use optional chaining to concisely handle the undefined case:

const longFieldName = f?.config.longFieldName;  // OK, type is string | undefined

But now I have to repeat longFieldName.

Can I have my cake and eat it, too? Can I use optional chaining to handle the undefined case without repeating longFieldName? If not, what is the most concise/idiomatic workaround? See playground link.

Answer

Ori Drori picture Ori Drori · Nov 14, 2019

Use short circuit evaluation to get a fallback value (empty object) if the f?.config expression evaluate to undefined:

const { longFieldName } = f?.config || {};