Repository navigation
3.7-beta regression: Promise.all wrongly adds undefined type #33752
Description
Activity
jack-williams commented
on Oct 2, 2019 CollaboratorMore actionsSwatinem commented
on Oct 2, 2019 ContributorAuthorMore actionsHm, but maybe #33707 will resolve this regression? That’s what I thought, haven’t checked though.
jack-williams commented
on Oct 2, 2019 CollaboratorMore actionsReduced repo:
interface A { a: string } interface B { b: string } interface Foo { all<T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; } declare const Foo: Foo; function main() { let aValue: A; Foo.all([Promise.resolve({a: "a"} as A), Promise.resolve({b: "b"} as B | undefined)]).then(([a,b]) => aValue = a); }
Error on assignment to
aValue; removingreadonlyremoves the error.jack-williams commented
on Oct 2, 2019 CollaboratorMore actionsYes, the typings in #33707 fix the smaller repro above.
Reacted by Arpad Borsos and ExE Boss- added a commit that references this issue
on Oct 3, 2019 - addedBugA bug in TypeScriptA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptThe issue relates to the different libraries shipped with TypeScript
on Oct 17, 2019 Here is another case of this: #34554
sed -i 's|: readonly|:|g' node_modules/typescript/lib/lib.es2015.promise.d.tsseems to be an effective temporary workaround until this is fixed.Ryan Lester (@buu700) how do you recommend using that work around? running that command prior to compile every time?
Ryan Cavanaugh (@RyanCavanaugh) this seems like a pretty major regression, is there any timeline here? I see this immediately on upgrading all around my code base.
Reacted by Hendrik Liebau, Ryan Lester, Liam Doran, Skyler Jokiel, JasonKleban, Brian Kim and KostaYou could use the attached patch with patch-package, or possibly run that sed command (or a JS equivalent) in a postinstall script.
Ryan Lester (@buu700) this is amazing. thank you so much for the suggestion extremely helpful!
Reacted by Ryan Lester and Greg HornbyI'm seeing a similar situation in Promise.all in 3.7.2 but types are being overwritten.
Ex. in the example below r1 should be of type
booleanand r2 should be of typeunknownbut actually they are both of typeunknown.const p1: Promise<boolean> = new Promise((resolve) => { resolve(true); }); const p2: Promise<unknown> = new Promise((resolve) => { resolve(); }); const [r1, r2] = await Promise.all([p1, p2]);
If
p2:Primose<undefined>then r1 and r2 are of typeboolean | undefined11 remaining items
sed -i 's|: readonly|:|g' node_modules/typescript/lib/lib.es2015.promise.d.tsseems to be an effective temporary workaround until this is fixed.Is there any reason my fix from November (quoted above) can't or shouldn't be used?
I don't mind continuing to patch TypeScript in my own projects as a temporary workaround, but it just seems odd that such a high-impact regression with a simple quick fix available is still an issue three months later.
Reacted by Toni Villena, Anton Ivanov, Nick Zelei, Anton Kropp, Jeff Malins, Brian Kim, Jefferson Roylance and Shengjie LuReacted by Anton IvanovReacted by Anton Ivanov and Nick ZeleiReacted by Tyler Johnson, Toni Villena and John GilbertSwatinem commented
on Feb 7, 2020 ContributorAuthorMore actionstbh, I’m a bit disappointed by the lack of communication here. I recently read the already month old Design notes here: #36138 which mention ideas to create a dedicated
awaitedorpromisedtype, which would maybe solve this, but is probably a very invasive change.
However, this is just speculation on my part. Some official clarification would be nice.Reacted by Toni Villena, Tyler Johnson, Jeff Malins, Steve, John Gilbert, Jose Quintana, Brian Kim and Jefferson Roylancev3.7.502.20 and I still facing the same issue onPromiseLiketypes vialib.es5.d.tsReacted by Toni Villena, Phoenix He and Oliver BellAssuming we merge the
awaitedtype PR, I plan to take a renewed look at all of thePromise-related issues in light of that change.Reacted by Hendrik Liebau, Toni Villena and Arpad Borsos- added 2 commits that reference this issue
on Feb 19, 2020 This issue can be worked around by adding this somewhere:
declare global { interface PromiseConstructor { all<T extends readonly any[] | readonly [any]>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>; } }
but I'd be really happy having this fixed, my devs are using this as an excuse to plaster Bluebird everywhere instead of using native promises.
Still exists in 3.9.0-dev.20200229
Reacted by Ryan Lester, Toni Villena, Liam Doran and Oleg VaskevichWe anticipate that our next version, TypeScript 3.9, will be coming mid-May of 2020, and will mostly focus on performance, polish, and potentially smarter type-checking for Promises.
Hopefully this issue will be fixed in 3.9
Reacted by Toni Villena, Anton Ivanov, Joseph Kohlmann and Zhenglai ZhangSeems this example still does not work on nightly.
(async () => { const [num1, num2] = await Promise.all([Promise.resolve(1), Promise.resolve(null)]); num1.toString(); })Is it really fixed?
Reacted by Rafal Sawicki, Toni Villena and Ryan LesterJust checked on
3.9.0-dev.20200317and it appears to be fixed. woohoo!Reacted by Ryan Lester, Fedor Paretsky, Joseph Kohlmann, Toni Villena and Fatih KalifaReacted by Anton IvanovNick Zelei (@nickzelei) Somehow my code above doesn't work on TypeScript playground yet. Perhaps their nightly version is not updated yet.
DanielRosenwasser commented
on Mar 23, 2020 MemberMore actionsThe playground seems to have a lot of weirdness there, specifically with
Promise.all. Things like signature help don't even seem to work correctly. I'm not sure exactly what the problem is, but if you do try that code out locally with a nightly version of TypeScript, it should all work fine.- addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Aug 7, 2021 - locked as resolved and limited conversation to collaborators
on Oct 21, 2025
TypeScript Version: 3.7.0-beta
Search Terms:
promise all
Code
Expected behavior:
This is a regression from 3.6.3, where the return tuple of
Promise.allis correctly inferred.Actual behavior:
A
| undefinedbound of a different tuple member also adds a| undefinedbound on a different unrelated return value ofPromise.all.Playground Link:
https://www.typescriptlang.org/play/?ts=3.7-Beta#code/JYOwLgpgTgZghgYwgAgILIN4ChnLgLmQGcwpQBzLAXy1ElkRQCFMdkAjQkskSmuIgE8QCZDACuIsMAD2IZAFs4oABQBKQgAUoMhcCIQAPKgB8rXAjklkAbTgAaDgF1kAXjwB3ZWGTbd+iAA6OAAbEJUbNlw-PQNAqAgiGRCANwgVDAJkACI4bKo8IjQ1eyjfHVighKTU9IxOHPZ8wuQWAB9kSQATCBhQCC6S5AB6YeRDAFpkMAALFAADDu7e-q755DmE5H1pueQABx12EIgFNic1AG42BLBxKHk4S5GxybwNgWnBfYX0JZAen0QAN5o52OIfEQZjJxCEuhxfvNqEA
Related Issues:
Maybe #33707 ?