94

TypeScript 3.7 now supports the optional chaining operator. Hence, you can write code such as:

const value = a?.b?.c;

I.e., you can use this operator to access properties of an object, where the object itself may be null or undefined. Now what I would like to do is basically the same, but the property names are dynamic:

const value = a?[b]?.c;

However, there I get a syntax error:

error TS1005: ':' expected.

What am I doing wrong here? Is this even possible?

The proposal seems to imply that this is not possible (but maybe I get the syntax examples wrong).

jonrsharpe
  • 107,083
  • 22
  • 201
  • 376
Golo Roden
  • 127,345
  • 89
  • 282
  • 404

2 Answers2

175

When accessing a property using bracket notation and optional chaining, you need to use a dot in addition to the brackets:

const value = a?.[b]?.c;

This is the syntax that was adopted by the TC39 proposal, because otherwise it's hard for the parser to figure out if this ? is part of a ternary expression or part of optional chaining.

The way I think about it: the symbol for optional chaining isn't ?, it's ?.. If you're doing optional chaining, you'll always be using both characters.

Nicholas Tower
  • 56,346
  • 6
  • 64
  • 75
  • 13
    I’d replace _hard_ with _impossible_. – vol7ron Nov 09 '19 at 16:17
  • @vol7ron why so - i think it can look forward for `:` – AnArrayOfFunctions Nov 09 '19 at 20:40
  • It wouldn’t be able to distinguish, especially when there are errors. – vol7ron Nov 09 '19 at 20:49
  • @AnArrayOfFunctions Won't happen. There are already a few places in the language where this forward-looking would solve problems. Just think how the statement `function(){};` or `{a: 1}.a;` are both a syntax error. Also: Nested ternaries are already hard to parse (what does `a?[...b][1]?c:d?.e:f` mean). Better not make it more difficult by overloading `?`. – Robert Jul 21 '20 at 05:10
  • Wow, that is super-unintuitive since the optional chaining syntax minus the "optional" part is invalid. You can't run chaining as `a.[b].c`, so `a?.[b]?.c` is only going to be discovered by those who run into the issue and search online. Maybe a proposal could be made to enable `a.[b].c` chaining syntax? – bsplosion Jun 04 '21 at 13:49
12

The Optional Chaining operator is ?.

Here are some examples for nullable property and function handling.

const example = {a: ["first", {b:3}, false]}

// Properties
example?.a  // ["first", {b:3}, false]
example?.b  // undefined

// Dynamic properties ?.[]
example?.a?.[0]     // "first"
example?.a?.[1]?.a  // undefined
example?.a?.[1]?.b  // 3

// Functions ?.()
null?.()                // undefined
validFunction?.()       // result
(() => {return 1})?.()  // 1

Bonus: Default values

?? (Nullish Coalescing) can be used to set a default value if undefined or null.

const notNull = possiblyNull ?? defaultValue
const alsoNotNull = a?.b?.c ?? possiblyNullFallback ?? defaultValue
Gibolt
  • 33,561
  • 12
  • 157
  • 107