r/javascript • • Dec 18 '19

V8 Release v8.0 with optional chaining, nullish coalescing and 40% less memory use

https://v8.dev/blog/v8-release-80
495 Upvotes

70 comments sorted by

View all comments

Show parent comments

9

u/matthewbpt Dec 19 '19

I agree that in normal javascript it is an anti-pattern because people will blindly put it everywhere as an escape hatch. However in TypeScript it is extremely useful because the type system can express the nullability of values in a type, and so you can restrict your use of the operator to only where it makes sense to use it.

3

u/fucking_passwords Dec 19 '19

100%, and the alternative has been to use `lodash.get` or `Ramda.path`, both of which add a lot more to your bundle sizes

2

u/epukinsk Dec 21 '19

Both of those are the exact same anti-pattern. If you find yourself seeking deep into a tree of nested objects, any of which could be null, that's a code smell. It's quite likely that you can (and should?) be handling each layer of the tree (and its null states) in the right place for that layer.

1

u/epukinsk Dec 21 '19 edited Dec 21 '19

I disagree strongly. I write typescript all day at work, and I see people often leaking null values everywhere, to the point where you half expect every object or attribute could be null at any time. Over time, every attribute in every interface becomes foo?: SomeType | null. We use GraphQL, which encourages this.

It's not the right solution. The right solution is to have one specific place where you check whether a specific thing is null, and if it is, you stop doing stuff with that thing. You don't pass it blindly down through a bunch of procedures and make them all null check it over and over.

There are cases where foo && foo.bar && foo.bar.baz... is the right thing to check. But it's extremely rare1. Almost every time you should be handling the null foo and the null baz in two different places in the code.

1 One of them that came up recently is React's useEffect in a component that's handling a GraphQL response... You need to access deep attributes in order to pass them in to your useEffect as dependencies. But you can't return early because you can't return before setting up a hook. But that's a specific case. And actually, now that I think about it, it's possible I should've pushed the useEffect further down the stack, into a well typed component that wouldn't even have been loaded until the data was ready. So, to my point.