Closed
Description
TypeScript Version: 3.7.2
Search Terms: optional chaining, non null operator
Code
This input
a?.b!.c
will compile to
((_a = a) === null || _a === void 0 ? void 0 : _a.b).c;
But it's unsafe, because if a
is null
or undefined
, will throw an exception:
((_a = a) === null || _a === void 0 ? void 0 : _a.b).c
=> ((_a = null) === null || _a === void 0 ? void 0 : _a.b).c
=> (null === null || _a === void 0 ? void 0 : _a.b).c
=> (true ? void 0 : _a.b).c
=> undefined.c
IMO we should not raise this exception.
Expected behavior:
Would be better to compile to
(_a = a) === null || _a === void 0 ? void 0 : _a.b.c;
So a
could be null or undefined and it'll not raise an exception anymore.
Playground Link: Playground
Related Issues: There was a lot of discussion here, but was more focused in the type system, not about the code output that raise wrongly an exception.
- Non-null type assertions shouldn't affect optional chaining #34875
- Non-null assertions infringe a responsibility of optional chaining #35025
!.
after?.
should be warned #35071
Also this bug was reported in Babel and already there is a PR to fix that in Babel:
- issue: a?.b.c() produces different result than a?.b!.c() babel/babel#10959
- pr: fix: optional-chaining should work correctly with ts non-null operator babel/babel#10961
In this issue I'm saying only about the output, not about the type system.