4 ms·
I feel really excited about 3.7. Optional chaining and null coalescing will clean up a TON of code. ... but with that being said, 3.7 seems to have broken man
by SirensOfTitan 7y ago
I feel really excited about 3.7. Optional chaining and null coalescing will clean up a TON of code.
... but with that being said, 3.7 seems to have broken many aspects of the `Promise.all` interface. Right now the largest issue seems to be that if any `Promise` result in `Promise.all` is nullable, all of the results are nullable.
- nine_k 7y agoIndeed, how can you declare a list with some elements nullable, and some not? The result should instead be a tuple, but IDK how well tuple size inference would work in a case like that.
- 52-6F-62 7y agoI’m not at a computer now, but you can explicitly define a tuple type like: type Tuple<T, K> = [T, K | null]; Which is my first thought, but I can’t test it against the compiler at the moment and I’m not sure if I’m missing something. ...JavaScript would allow you to extend that list during runtime (unless you freeze it) type Tuple<T, K> = [T, K] const Tuple<T, K> = (x: T, y: K): Tuple<T, K> => { const tup = [x, y]; Object.freeze(tup); return tup; };
- amaranth 7y agoHaving it be a tuple would require variadic generics, wouldn't it?
- Klathmon 7y agoThis is a moment where the postfix `!` operator comes in handy. It is a well hidden secret, and one that I'm not going to try to lookup the docs for on mobile, but the idea is that the operator strips null/undefined from the type of whatever is before it. So you can do something like this: const [ a, b ] = await Promise.all([ async () => ({ foo: 'bar' }), () => null ]) console.log(a!.foo) // `a!` strips the nullable off `a`
- shhsshs 7y agoWhen I plug in your example (in Chrome console and in the TypeScript compiler), `a` is type `() => Promise<{foo: string}>` and `b` is type `() => any`. I thought you had to actually provide a Promise to `Promise.all`, not functions that return promises (you have to invoke the functions): const [ a, b ] = await Promise.all([ (async () => ({ foo: 'bar' }))(), (() => null)(), ]) When I do this, `a` and `b` have their proper types.
- Klathmon 7y agoAh good catch, I was spacing on the easiest way to show how to easiest show the operator and forgot to invoke my functions!
- graup 7y agoThe problem is that Promise.all stopped infering tuple types. Promise.all([() => A, () => B]) should be Promise<[A, B]> but is now Promise< (A | B) [] >. This issue is being tracked here and a fix seems to be already in the making: https://github.com/microsoft/TypeScript/issues/33752 https://github.com/microsoft/TypeScript/issues/33752 https://github.com/microsoft/TypeScript/pull/33707 https://github.com/microsoft/TypeScript/pull/33707
- SirensOfTitan 7y agoYeah, thank you. I think it's questionable they shipped with this kind of regression present (especially having known about it 1 month before release), but easy fix just to override core types with the one in #33707.