Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor error message due to Iterable overload in Promise.all #46669

Open
DanielRosenwasser opened this issue Nov 3, 2021 · 0 comments
Open

Poor error message due to Iterable overload in Promise.all #46669

DanielRosenwasser opened this issue Nov 3, 2021 · 0 comments
Labels
Domain: Error Messages The issue relates to error messaging Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@DanielRosenwasser
Copy link
Member

Found in #46651

Bug Report

Playground Link

interface Apples { type: "apples" }
interface Bananas {  type: "bananas" }

declare function getApples(): Promise<Apples[]>;
declare function getBanoonoos(): Promise<Bananas[]>;

declare function goodPromiseAll<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>;

declare function badPromiseAll<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;
declare function badPromiseAll<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>;

async function getBranchesOrTags(condition?: boolean) {
    await badPromiseAll<[Apples[] | undefined, Bananas[] | undefined]>([
        condition ? getApples() : undefined,
        condition ? getBanoonoos() : undefined,
    ]);
swa}

Try swapping between goodPromiseAll and badPromiseAll.

Notice that the errors on goodPromiseAll are

|         condition ? getApples() : undefined,
|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Type 'Promise<Bananas[]> | undefined' is not assignable to type 'Bananas[] | undefined'.
  Type 'Promise<Bananas[]>' is missing the following properties from type 'Bananas[]': length, pop, push, concat, and 26 more.

|         condition ? getBanoonoos() : undefined,
|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Type 'Promise<Apples[]> | undefined' is not assignable to type 'Apples[] | undefined'.
  Type 'Promise<Apples[]>' is missing the following properties from type 'Apples[]': length, pop, push, concat, and 26 more.

and on badPromiseAll there's one bad error:

| async function getBranchesOrTags(condition?: boolean) {
|     await badPromiseAll<[Apples[] | undefined, Bananas[] | undefined]>([
|                                                                        ~        
|         condition ? getApples() : undefined,
|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|         condition ? getBanoonoos() : undefined,
|         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|     ]);
|     ~

No overload matches this call.
  Overload 1 of 2, '(values: Iterable<[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>>): Promise<...>', gave the following error.
    Argument of type '(Promise<Apples[]> | Promise<Bananas[]> | undefined)[]' is not assignable to parameter of type 'Iterable<[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>>'.
      The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
        Type 'IteratorResult<Promise<Apples[]> | Promise<Bananas[]> | undefined, any>' is not assignable to type 'IteratorResult<[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>, any>'.
          Type 'IteratorYieldResult<Promise<Apples[]> | Promise<Bananas[]> | undefined>' is not assignable to type 'IteratorResult<[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>, any>'.
            Type 'IteratorYieldResult<Promise<Apples[]> | Promise<Bananas[]> | undefined>' is not assignable to type 'IteratorYieldResult<[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>>'.
              Type 'Promise<Apples[]> | Promise<Bananas[]> | undefined' is not assignable to type '[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>'.
                Type 'undefined' is not assignable to type '[Apples[] | undefined, Bananas[] | undefined] | PromiseLike<[Apples[] | undefined, Bananas[] | undefined]>'.

I don't understand why we always use the Iterable overload in badPromiseAll regardless of the ordering.

🕗 Version & Regression Information

4.5, nightly

@DanielRosenwasser DanielRosenwasser added Domain: Error Messages The issue relates to error messaging In Discussion Not yet reached consensus Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. and removed In Discussion Not yet reached consensus labels Nov 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Error Messages The issue relates to error messaging Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

1 participant