You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Promise.all returns all values with type of the most common interface. #16017
20 const dataB: B[] = resultB;
~~~~~
promise-all-issue.ts(20,11): error TS2322: Type 'A[]' is not assignable to type 'B[]'.
Type 'A' is not assignable to type 'B'.
Property 'fieldB' is missing in type 'A'.
I see that interface B is compatible with interface A, but I don't think that Promise.all should return all values as A[].
When you change interface A for example adding a field fieldA, then interface B is not compatible anymore and the code compiles without errors.
Looks like the issue here is we have two definitions for Promise.all, one in lib.es2015.promise.d.ts and one in lib.es2015.iterable.d.ts, the earlier defines a set of overloads with a tuple types and thus get type of [dataA, dataB] correctly, the other has an array overload, that takes a list and returns a list, and thus gets the type as the best common type between A and B.
The fix seems to reorder these overloads somehow to make sure the overloads from lib.es2015.promise.d.ts come after lib.es2015.iterable.d.ts,; or that lib.es2015.iterable.d.ts, redefines the same overloads.
As a workaround, list the --lib explicitly with this order: --lib es5,es2015.promise,es2015.iterable
But it is still not very clear what to specify there if I target the browser and want to have available all features polifilled by core.js for instance. Should I specify es2015 or es2016 or es2016.array.include if I have already specified es2017?
Is there somewhere better documentation about all of this?
--target is what version of ECMAScript is your target engine supporting. for instance --target ES5 would be safe if you are using IE11. --target ES2017 is safe if you are using node@7.0.
By default a matching version of the library is added to your compilation based on your target, so --target ES6 gets you the equivalent lib.es6.d.ts, and --target ES2017 gets you lib.es2017.d.ts. By default you also get things like DOM APIs.
Sometimes you want to add definitions that are not part of the standard, for instance ones you have polyfiled, e.g. Promise. for these we recommend explicitly adding the library portion that you need, e.g. --target es5 --lib es5,es2015.promise.
Library versions are cumulative, so if you set --lib es2017 this includes definitions in es2017, es2016 and es5.
Andy (Andrewkraft) (@Andy-MS) it is because we pick up overload all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; from lib.es2015.iterable.d.ts due to how it is order.
I think the fix here is to remove Promise constructor definition from lib.es2015.iterable.d.ts and just reference ``lib.es2015.promise.d.ts`
Activity
mhegazy commentedon May 23, 2017
Looks like the issue here is we have two definitions for
Promise.all, one inlib.es2015.promise.d.tsand one inlib.es2015.iterable.d.ts, the earlier defines a set of overloads with a tuple types and thus get type of[dataA, dataB]correctly, the other has an array overload, that takes a list and returns a list, and thus gets the type as the best common type betweenAandB.The fix seems to reorder these overloads somehow to make sure the overloads from
lib.es2015.promise.d.tscome afterlib.es2015.iterable.d.ts,; or thatlib.es2015.iterable.d.ts, redefines the same overloads.As a workaround, list the
--libexplicitly with this order:--lib es5,es2015.promise,es2015.iterablemegaboich commentedon May 24, 2017
Thanks Mohamed Hegazy (@mhegazy)!
I have applied your workaround and may confirm it works.
I modified my tsconfig.json to include this:
Still I find this
--liboption a bit confusing, I have read specifications here:https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#including-built-in-type-declarations-with---lib
But it is still not very clear what to specify there if I target the browser and want to have available all features polifilled by
core.jsfor instance. Should I specifyes2015 or es2016 or es2016.array.includeif I have already specifiedes2017?Is there somewhere better documentation about all of this?
mhegazy commentedon May 24, 2017
--targetis what version of ECMAScript is your target engine supporting. for instance--target ES5would be safe if you are using IE11.--target ES2017is safe if you are using node@7.0.By default a matching version of the library is added to your compilation based on your target, so
--target ES6gets you the equivalentlib.es6.d.ts, and--target ES2017gets youlib.es2017.d.ts. By default you also get things likeDOMAPIs.Sometimes you want to add definitions that are not part of the standard, for instance ones you have polyfiled, e.g.
Promise. for these we recommend explicitly adding the library portion that you need, e.g.--target es5 --lib es5,es2015.promise.Library versions are cumulative, so if you set
--lib es2017this includes definitions ines2017,es2016andes5.hope that helps.
yuit commentedon Jun 15, 2017
Andy (Andrewkraft) (@Andy-MS) it is because we pick up overload
all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>;fromlib.es2015.iterable.d.tsdue to how it is order.I think the fix here is to remove Promise constructor definition from
lib.es2015.iterable.d.tsand just reference ``lib.es2015.promise.d.ts`