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

Add BuiltinIteratorReturn to IterableIterator and AsyncIterableIterator return types #1713

Merged
merged 18 commits into from
Aug 8, 2024

Conversation

rbuckton
Copy link
Member

@rbuckton rbuckton commented May 7, 2024

This is a follow-on PR to microsoft/TypeScript#58243 to add BuiltinIteratorReturn to all IterableIterator and AsyncIterableIterator return types.

TODO:

  • Update the "typescript" dependency in package.json to a shipping version that supports BuiltinIteratorReturn and the TReturn type parameter for IterableIterator/AsyncIterableIterator
  • Update README.md to indicate the minimum TypeScript version

@@ -3,6 +3,6 @@
/////////////////////////////

interface ReadableStream<R = any> {
[Symbol.asyncIterator](options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
values(options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
[Symbol.asyncIterator](options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R, BuiltinIteratorReturn>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So BuiltinIteratorReturn can't be the default value to reduce verbosity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be the default value because it's not the default behavior of any iterator, just the native ones provided by the host. User-defined iterables might not match that behavior, and we don't intend to break those cases unnecessarily.

@rbuckton
Copy link
Member Author

@jakebailey could you review? Also, what is the correct approach to handling the typescript reference in package.json here?

@rbuckton
Copy link
Member Author

I've reverted the package.json/package-lock.json changes, but tests will fail until we at least have a nightly to point to

@jakebailey
Copy link
Member

jakebailey commented Jul 19, 2024

Yeah, I would just wait for a nightly.

If we really, really, really need it, we can run pack this on a PR and then reference the "pr-deploys" one on npm. (The artifact is ephemeral so shouldn't be used.)

Copy link
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems correct; feel free to use a PR build from pr-deploys if you want to be sure before tomorrow.

@rbuckton rbuckton marked this pull request as ready for review July 19, 2024 21:59
@saschanaz
Copy link
Contributor

saschanaz commented Jul 20, 2024

You might want to update TS dependency to nightly to fix the test. (Edit: #1713 (comment) already mentioned it)

@jakebailey
Copy link
Member

Updated it to help things along.

@jakebailey
Copy link
Member

Yay, green!

@petamoriken
Copy link
Contributor

IMO, BuiltinAsyncIterator is better name (microsoft/TypeScript#58222 (comment)).

@rbuckton
Copy link
Member Author

IMO, BuiltinAsyncIterator is better name (microsoft/TypeScript#58222 (comment)).

Honestly, I agree. I'll change it.

@rbuckton
Copy link
Member Author

The last commit aligns the generator with microsoft/TypeScript#59388

@rbuckton
Copy link
Member Author

I'll update this to the nightly tomorrow before merging

@rbuckton
Copy link
Member Author

How will this change affect @types/web publishing given that it has a dependency on TS 5.6+ for the BuiltinIterator and BuiltinAsyncIterator types? Would it just be published as @types/[email protected] (or similar) with an entry in the README.md, or do we have some other mechanism of ensuring the correct TS version, such as adding an entry to peerDependencies?

@jakebailey
Copy link
Member

I'm not 100% certain; the readme for the @types/web package claims compatibility with even TS 4.5, and in general support for old versions. This PR would change that to only support 5.6, so we would need to wait to publish this package for a while, and then it would break compat.

Does @types/web publishing / usage support typesVersions, maybe?

@rbuckton
Copy link
Member Author

It probably could, by tweaking deploy\createTypesPackages.js slightly to add a typesVersions entry, though we'd have to generate two sets of types: one using IterableIterator for older TS, and one using BuiltinIterator for newer TS.

@saschanaz
Copy link
Contributor

saschanaz commented Jul 24, 2024

Maybe either bump the minor version or add type AsyncIterableIterator<R> = BuiltinAsyncIterator<R, BuiltinIteratorReturn> in the TS side for better compat? (Because this would also become headache for other definitelytyped packages)

@jakebailey
Copy link
Member

This LGTM but do we need to come up with some typesVersions something to make things not break for old TS versions? Or just remove the language about TS version support?

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

To bump semver here I think someone with npm permission will have to manually deploy a new set of packages as 0.1.0 and then the deploy script should automatically make future versions as 0.1.x.

/** @type {*} */
const npmPackage = await npmResponse.json();
const semverMarkers = npmPackage["dist-tags"].latest.split(".");
const bumpedVersion = `${semverMarkers[0]}.${semverMarkers[1]}.${
Number(semverMarkers[2]) + 1
}`;

Is a semver bump necessary if we add "typesVersions" to disambiguate?

@jakebailey
Copy link
Member

I don't think we need to bump semver if we are just adding a typesVersions; adding that is not a backwards incompatible change (otherwise we'd be totally dead on DT)

@jakebailey
Copy link
Member

Do the baselines also need the 5.5 variants? (I think so?)

@saschanaz
Copy link
Contributor

Oh, TIL that and sounds nice. I guess it's fine in that case.

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

Do the baselines also need the 5.5 variants? (I think so?)

They did, yes. I just pushed up a commit that checks them.

I think this should be ready for one more review pass.

@jakebailey
Copy link
Member

Actually, do typesVersions work with lib replacement? I think so, reading pathForLibFile, given it seems to still go through regular module resolution? Would be good to quick double check the PR against 5.5 and 4.9. Wish we tested the list of supported versions here too.

Otherwise, things look correct to me.

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

Actually, do typesVersions work with lib replacement? I think so, reading pathForLibFile, given it seems to still go through regular module resolution? Would be good to quick double check the PR against 5.5 and 4.9. Wish we tested the list of supported versions here too.

Otherwise, things look correct to me.

I'll test that locally and report back shortly.

@saschanaz
Copy link
Contributor

It would be nice to have some CI for that here, but I guess that can be done separately.

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

"typesVersions" works, but the autoImports behavior in createTypesPackages.js is causing problems. I'm surprised autoImports is a thing as it seems like it would conflict with --target ES5 since dom.iterable.generated.d.ts tries to load Symbol but it wouldn't exist.

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

The last commit should fix the autoImport reference path added to the index of each @types package, and I've verified "typesVersions" is working correctly for both 5.5.4 and 5.6.0-dev.

@saschanaz
Copy link
Contributor

The question would be that whether it works in 4.4 or otherwise it will still be a breaking change 🤔

@rbuckton
Copy link
Member Author

rbuckton commented Aug 6, 2024

I've tested it and it works fine with 4.4 as well. I mentioned 5.5 since that's where the split occurs as a result of the "typesVersions" entry, so 5.5.* and earlier (incl 4.4) will use the version in the ts5.5 directory, while 5.6.0-dev and later will use the version in the root.

@jakebailey
Copy link
Member

TS 4.4 is well out of support on DT (and that's what most tools use as their window), so I wouldn't worry about that too much. But good that it works!

@saschanaz
Copy link
Contributor

(Maybe this should also use DT window)

try {
outputFiles = fs.readdirSync(outputFolder);
} catch {
// do nothing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we actually expecting an error here? This looks like it could potentially silence a real failure 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the failures that matter are mismatched files. If either the input or output dir don't exist, then the file mismatch will be reported when we traverse whichever side did exist and find the file on the other side is missing.

This actually catches more failures as we previously only checked what was in baseline and ignored new things in generated. This now enumerates all distinct entries from both so we will report on excess baselines or excess outputs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but we call stat before entering directory, so not sure this one matters.

Copy link
Member Author

@rbuckton rbuckton Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We call stat on both, but we still traverse the directory if the stat only succeeded on one side or the other, so the readddir can still potentially fail.

@@ -2,14 +2,22 @@
/// Window Async Iterable APIs
/////////////////////////////

interface FileSystemDirectoryHandleAsyncIterator<T> extends AsyncIteratorObject<T, BuiltinIteratorReturn, unknown> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this, is FooAsyncIterator basically same as BarAsyncIterator, because I don't see a difference between this and ReadableStreamAsyncIterator below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They have independent prototypes on the web, so you could theoretically augment ReadbleStreamAsyncIterator independently via its prototype:

var rs = new ReadableStream();
var proto = Object.getPrototypeOf(rs[Symbol.asyncIterator]());
proto; // [object ReadableStream AsyncIterator]

As with ArrayIterator, MapIterator, SetIterator, etc., we've opted to use interface names that more closely align with the underlying prototype.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They have independent prototypes because the underlying iterator algorithms are different, but I wouldn't expect any independent members on them that would require separate declarations, at least not in the foreseeable future, because Web IDL simply doesn't have syntax for that and I don't see why IDL would want that.

@MattiasBuelens may have some opinion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the general principle we've agreed on in microsoft/TypeScript#58243 and in design meeting is to try to give these things a relevant name. BuiltinIterator was too broad and confusing, and IteratorObject<T, BuiltinIteratorReturn, unknown> was too unwieldy and verbose. Since we must give these names, we've opted to give them names that reflect the actual runtime reality.

Copy link
Contributor

@saschanaz saschanaz Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm. I guess it would be fine as we don't have too many iterable interfaces here, and also matching with TS principle makes sense. I still worry that this would encourage people do weird things that doesn't fit the spec intention though.

@rbuckton
Copy link
Member Author

rbuckton commented Aug 7, 2024

@saschanaz: any other concerns or feedback before this is merged?

@saschanaz
Copy link
Contributor

Besides what I already said, otherwise I'm good.

@rbuckton rbuckton merged commit 907f5dc into main Aug 8, 2024
6 of 16 checks passed
@rbuckton rbuckton deleted the builtiniteratorreturn branch August 8, 2024 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants