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

Confusing error for custom Promise type #16993

Closed
ghost opened this issue Jul 7, 2017 · 3 comments
Closed

Confusing error for custom Promise type #16993

ghost opened this issue Jul 7, 2017 · 3 comments
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@ghost
Copy link

ghost commented Jul 7, 2017

TypeScript Version: nightly (2.5.0-dev.20170629)

Code

export declare class TPromise<T> {
	constructor(executor: (resolve: (value?: T /*| PromiseLike<T>*/) => void, reject: (reason?: any) => void) => void);

	// Copy-pasted from PromiseLike:
	then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
}

async function f(resource: any): TPromise<number> { return 0; }

Expected behavior:

Complains that constructor is not compatible with Promise's constructor. (Uncomment | PromiseLike<T> and there is no compile error.)

Actual behavior:

Complains that then is incompatible. But it's identical to the one in PromiseLike.

src/a.ts(8,34): error TS1055: Type 'typeof TPromise' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
src/a.ts(8,34): error TS1055: Type 'typeof TPromise' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
  Type 'TPromise<T | PromiseLike<T>>' is not assignable to type 'PromiseLike<T>'.
    Types of property 'then' are incompatible.
      Type '<TResult1 = T | PromiseLike<T>, TResult2 = never>(onfulfilled?: (value: T | PromiseLike<T>) => TR...' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, on...'.
        Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
          Types of parameters 'value' and 'value' are incompatible.
            Type 'T | PromiseLike<T>' is not assignable to type 'T'.
              Type 'PromiseLike<T>' is not assignable to type 'T'.

Discovered in microsoft/vscode#30216

@mhegazy mhegazy added the Needs Investigation This issue needs a team member to investigate its status. label Aug 23, 2017
@HunderlineK
Copy link

Possibly related:

type FindByToken = Promise<IUserDocument | null>;

UserSchema.statics.findByToken = async function(token: string): FindByToken {

Will complain,

but

UserSchema.statics.findByToken = async function(token: string): Promise<IUserDocument | null> {

will be fine

@rbuckton
Copy link
Member

rbuckton commented May 6, 2018

@HunderlineK If you are targeting ES5 then you cannot use a type alias in the return type of an async function as the return type must resolve to a constructor in the value space, not just the type space.

@RyanCavanaugh
Copy link
Member

Doesn't seem like anyone else has encountered this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

4 participants