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

Doesn't quite match AsyncIterable interface? #56

Open
jedwards1211 opened this issue Mar 24, 2020 · 3 comments
Open

Doesn't quite match AsyncIterable interface? #56

jedwards1211 opened this issue Mar 24, 2020 · 3 comments

Comments

@jedwards1211
Copy link
Contributor

I don't know if this causes problems in TS, but I noticed it because I'm trying to convert the defs to Flow, so I wanted to point it out.

The AsyncIterator interface is

// es2018.asyncgenerator.d.ts
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> 
    extends AsyncIterator<T, TReturn, TNext> {
    // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors
    // in all places.
    next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
    return(value: TReturn): Promise<IteratorResult<T, TReturn>>;
    throw(e: any): Promise<IteratorResult<T, TReturn>>;
    [Symbol.asyncIterator](): AsyncGenerator<T, TReturn, TNext>;
}

next and return don't accept PromiseLike the way they do in Repeater.

@brainkim
Copy link
Member

brainkim commented Mar 24, 2020

Is that the typescript definition? I’m pretty sure return accepts PromiseLike parameters:
https://github.com/microsoft/TypeScript/blob/master/lib/lib.es2018.asynciterable.d.ts#L32-L37
If you call return with a promise-like it will await the argument. It’s a weird thing that never happens but whatever.

As for next, Repeater.prototype.next is assignable to AsyncGenerator.prototype.next because the latter’s parameters are assignable to the former’s parameters (contravariance). If you think about it (value: number | Promise<number>) => any is assignable to (value: number) => any, while (value: number) => any is not assignable to (value: number | Promise<number>) => any. Same with Repeater.prototype.next. Again, I’m not really sure there’s a use-case here, it was more a consequence of the fact that the value returned from the push function resolves to the parameter passed to next, so we might as well allow it to be a PromiseLike.

If you need help with flow stuff or any other questions let me know!
Brian

@jedwards1211
Copy link
Contributor Author

ah okay, they've updated the interface from whatever I found, which I think was one of the first commits of it

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 25, 2020

FWIW the spec says this behavior isn't enforced...

If the argument value is used in the typical manner, then if it is a rejected promise, a promise rejected with the same reason should be returned; if it is a fulfilled promise, then its fulfillment value should be used as the value property of the returned promise's IteratorResult object fulfillment value. However, these requirements are also not enforced.

But I guess the TS declarations enforce this on anything implementing the TS AsyncIterator interface.

The flow defs are so messed up sigh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants