0

I have this code snippet.

interface OBJ {
  a: {
    b?: {
      c?: number;
    };
  };
}

const obj: OBJ = {
  a: {
    b: {
      c: 1
    }
  }
};

if (obj.a.b.c === 1) {
  console.log("here");
}

Firstly the TS compiler complains about Object is possibly 'undefined'.ts(2532) at obj. I don't get it since it looks to me like the object is indeed defined, it is just according to the interface the b and c property can be undefined.

then I thought I could use optional chaining on it

if (obj.a.b?.c === 1) {
  console.log("here");
}

However this time the compiler says there is a syntax error

/src/index.ts: Unexpected token (9:14)

   7 |     }   
   8 | };
>  9 | if (obj.a.b ? .c === 1 : ) {
     |              ^   
  10 |     console.log("here");
  11 | }
  12 | //#

What am I missing here? Can someone please explain these two questions to me?

live demo: https://codesandbox.io/s/wizardly-booth-idpy5?file=/src/index.ts

3
  • 1
    Object is possibly 'undefined'.ts because you're accessing it through the OBJ interface, the actual value doesn't matter. And the second one is complaining about the whitespace - you've mixed up a ternary operator into your code for some reason, it's not optional chaining.
    – jonrsharpe
    Commented Sep 7, 2020 at 19:03
  • still don't understand why accessing it through the OBJ interface would result in Object is possibly 'undefined'
    – Joji
    Commented Sep 7, 2020 at 19:16
  • Because you said b and c are optional.
    – jonrsharpe
    Commented Sep 7, 2020 at 19:16

2 Answers 2

2

Firstly the TS compiler complains about Object is possibly 'undefined'.ts(2532) at obj. I don't get it since it looks to me like the object is indeed defined, it is just according to the interface the b and c property can be undefined.

Yes, compiler shows that b can be undefined. This message is not about the a. You can easily check this by changing if (obj.a === 1) - no error now.

The construction if (obj.a.b?.c === 1) will be converted to if (((_a = obj.a.b) === null || _a === void 0 ? void 0 : _a.c) === 1) after compile. I prefer using old good guards:

if (obj.a.b && obj.a.b.c === 1) {
  console.log("here");
}

However this time the compiler says there is a syntax error

This is strange. Since TS 3.7 this should not be an error. Take a look on another online sandbox: click. You will see there is no error here.

0

To extend the answer by @Anton

You are using parcel bundler in your sample. You need to tell parcel which version of typescript to use (the one that supports optional chaining operator) and the error will go away.

package.json:

"devDependencies": {
    "parcel-bundler": "^1.6.1",
    "typescript": "^4.0.2"
},
1

Not the answer you're looking for? Browse other questions tagged or ask your own question.