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

Regression of disposable async iterators (#59633) #60654

Closed
james-pre opened this issue Dec 2, 2024 · 2 comments
Closed

Regression of disposable async iterators (#59633) #60654

james-pre opened this issue Dec 2, 2024 · 2 comments
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@james-pre
Copy link

james-pre commented Dec 2, 2024

⚙ Compilation target

N/A

⚙ Library

ESNext, Typescript 5.7.2

Missing / Incorrect Definition

AsyncIterator is missing a [Symbol.asyncDispose] property. I found this after investigating a type error I got while creating a polyfill of node:fs's ReadStream. You can follow the rabbit hole here: DefinitelyTyped/DefinitelyTyped#71307.

At the end, I discovered that AsyncIteratorObject has the [Symbol.asyncDispose] property (from #59633) and since AsyncIterator doesn't extend AsyncIteratorObject, it is missing the property. In fact, AsyncIteratorObject extends AsyncIterator.

Sample Code

declare const it: AsyncIterator<any>;

it[Symbol.asyncDispose](); // <-- error!

Error:

Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'AsyncIterator<any, any, any>'.
  Property '[SymbolConstructor.asyncDispose]' does not exist on type 'AsyncIterator<any, any, any>'.ts(7053)

Documentation Link

I wasn't able to independently find anything in the ECMAScript specification or on MDN, so the only reference I have is #59633

Fix

This can be fixed by having AsyncIterator extend AsyncDisposable.

james-pre added a commit to james-pre/TypeScript that referenced this issue Dec 2, 2024
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Dec 2, 2024
@Jamesernator
Copy link

Jamesernator commented Dec 2, 2024

At the end, I discovered that AsyncIteratorObject has the [Symbol.asyncDispose] property (from #59633) and since AsyncIterator doesn't extend AsyncIteratorObject, it is missing the property. In fact, AsyncIteratorObject extends AsyncIterator.

The AsyncIterator type doesn't refer to the builtin object of the same name because TypeScript already used it for the async iterator protocol where it already perfectly legal to have an async iterator that doesn't have [Symbol.asyncDispose].

The new AsyncIteratorObject is the builtin AsyncIterator object (i.e. the one on the prototype of async generators). That is what you should use in your example:

declare const it: AsyncIteratorObject<any>;

it[Symbol.asyncDispose](); 

declare class Broken implements AsyncItWithNode {
  it: AsyncIterableIterator<any>; // <-- error!
}

The error you are getting in the linked discussion is expected, an arbitrary async iterator doesn't have [Symbol.asyncDispose]. Only those that actually extend the builtin AsyncIterator object, or those that implement it themselves, do.


Also general warning, currently v8/Node doesn't actually implement Symbol.asyncDispose on the builtin AsyncIterator object yet anyway, if you need this functionality you should polyfill it.

@james-pre
Copy link
Author

Great, thanks. I'll look into resolving the issue on @types/node.

@james-pre james-pre closed this as not planned Won't fix, can't repro, duplicate, stale Dec 2, 2024
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

Successfully merging a pull request may close this issue.

4 participants