microsoft/TypeScript-DOM-lib-generator

DOM Lib Generator infra thread

orta opened this issue ยท 19 comments

orta commented

We would like to stop forcing the DOM dts files from being tied directly to a version of TypeScript, making migrations easier. In addition, we would like to give @saschanaz more control on this repo (they are doing a lot of work, and we should respect that)

With some of these constraints in mind, we think we've got a few ideas which work to address these:

  1. We treat this repo a bit like a mini-DefinitelyTyped. Giving it automation to ship packages to @types/xyz - specifically, today with the repo in the current state, we should be able to ship: @types/dom, @types/dom-webworker and @types/dom-serviceworker. All of these @types/x can be deployed automatically from master/main. #1025

    Because all the packages can live in the same repo, that makes it possible for us to expand to @types/dom-strict for example which would have some of the changes which were too breaking to apply across the entire ecosystem. e.g. #885

    Unsure if it's something we want to explore, but this does also open up the potential for DOM lib generator to ship types for things which may never pass our heuristics, like early-stage proposals or Chrome only APIs which come from WIDLs. Today we tell people to put those on DT. Some examples might have been @types/dom-web-vr (which never made it to a standard) or @types/dom-web-xr (which is still just chrome.)

  2. We add OSS-Docs-Tools/code-owner-self-merge to the repo for @saschanaz - covering src, baselines, input files & README.md (that seems to cover most PRs) - I'm also open to exploring something similar for issues. For repo security, we can keep the deployment infra in a separate folder and the code being shipped by default in TypeScript still need a manual PR to the TypeScript repo, where it can get audited for larger ecosystem impact there.

What this means for users

With these changes you:

  • Switch to a locked version of the DOM APIs
  • Get nightly builds as your PRs are merged
  • Potentially have a stricter version of the DOM apis
  • Potentially have a version of the DOM API with more fancy generics/template literals etc

Because we ship the dom APIs as a default in TypeScript, you would need to set your lib to be something like "lib": ["es2019"] (with es2019 being your target) instead of having lib missing (meaning dom won't be added by default) and then yarn add @types/dom.

How does this affect breaking changes?

The main dependency libdom.d.ts and @types/web have the same goals of backwards compatibility as prior to this work. We don't want to use @types/web as a way to ignore breaking changes. We already have tests that run the full TypeScript compiler test suite on every PR, and WIP for running DefinitelyTyped tests #1039 and an idea how to test against the Deno stdlib in #1027.

There is sufficiently good reason to ship larger breaking changes (for example using the template literal syntax in the DOM query APIs like #885 ) and these could live inside a 2nd DOM deploy.

How does this affect the security of @types?

Deploys are npm packages which are auto-generated from .d.tsfiles, which this repo creates. Any changes to the build and deploy infra require a TypeScript admin to accept the PRs.

What is a release?

As @types/web is released on every commit, eventually a specific version of the d.ts files in @types/web make their way into TypeScript. We can note the version of @types/web which corresponds to a specific release in TypeScript in the release notes, and in a table in the repo README here.

Backwards compatability

So far, I've stated that 4.4 is the minimum version of TypeScript which supports @types/web in part because I'm hoping to get the support for switching dom with @types/web in natively then. We can start a similar 2 year window to DT if we want, using downlevel-dts to support older syntax if needed.

  1. I wonder we can use "web" instead of "dom" in the names here. Things like WebXR have Web in their name because they are web APIs, and DOM is just a part of those web APIs: https://dom.spec.whatwg.org/.
    • Not sure what name webxr-specific package would have in this case. @types/web-webxr looks weird, @types/web-xr might make more sense...
  2. From #997 (comment): I also wonder we can split the current webworker into each worker type. The current one mixes things up and thus potentially confusing. With the upper suggestion, this would result @types/web-dedicatedworker instead of @types/dom-webworker.
orta commented

re: web vs dom - yeah, I think that's probably right- maybe we should call the 'main' export which replaces libdom @types/web-dom which can set the tone then (and perhaps we change this repo name eventually too.) MDN calls them all "Web APIs" which feels pretty accurate to me.

Yeah, #997 was kinda hitting my threshold for things we should be shipping with the TypeScript compiler - it's a natural fit for separate @types/web packages IMO.

maybe we should call the 'main' export which replaces libdom @types/web-dom which can set the tone then

web-dom sounds like its an additive package solely for DOM, I'd like to make it just @types/web. But since TS has long been using dom in the lib option, I can also accept web-dom blaming the historical reason.

Edit: Or alternatively it could be web-window matching web-serviceworker, but not sure I like it ๐Ÿ˜„

orta commented

I was figuring web-dom makes sense if you think as web as the namespace, and dom is as the core focus, but it does contain a lot of web APIs nowadays and I'm open to @types/web as the central name instead. I'm sure more folks think of these APIs as "the web" and not "the DOM".

Luckily all these small names don't have well used npm modules which we're not trampling on either.

It's worth pointing out that this will be opt-in -- the DOM types will still ship with Typescript and using @types/web-dom will require an explicit lib entry to exclude the built-in ones.

From our design meeting on Friday, I remember one issue is what DT packages like @types/jsdom, which extend DOM types, can do so that people can use @types/jsdom and @types/web-dom together. The compiler might need to add a special triple-slash comment for DOM replacements to identify themselves.

However, it's probably not a problem that needs to be solved immediately, since jsdom will continue to work with the built-in DOM types.

like early-stage proposals or Chrome only APIs which come from WIDLs.

BTW, I'm still not sure TS should promote such early ones in the field. There should at least be some warning that it's not well supported and the API form can still change.

orta commented

I think from our side we'll probably tell people about some of the biggies in the docs (dom/*worker/audiolet?) but change the README here to list all of them with some sort of 'and all these', so we won't be mentioning anything but the critical ones except very close to the source of truth

orta commented

So far, we have:

  • A PR to TypeScript adding types_web as the default dom.d.ts
  • Shipped @types/web 0.0.1 which represents TypeScript-DOM-lib-generator master (which is basically 4.3 libdom with a few additions)
  • Sent a bunch of PRs to types_web adding backwards compat types for changes which affect some of the biggest players I the ecosystem (react/angular/et al)
  • Sent a bunch of DT PRs which fix individual DT modules which had removed properties or types

All linked to microsoft/TypeScript#44684

orta commented

OK, types-web and this repo are now completely caught up. Version 0.0.2 is out which (roughly) represents the version we shipped as the 4.4 beta.

@saschanaz has the ability to merge PRs which don't affect deployment and CI infra, and the package json.

This looks like a huge achievement and will make things a lot easier going forward. Congratulations!

Could you help me understand whether the current state already addresses readable byte streams as suggested in #890 (comment)? Is there a clean way that I can add support for readable byte streams types in my library?

Congratulations on this huge achievement!

Is this the right place to report issues?

I've noticed that the correspondingElement & correspondingUseElement properties have been removed from SVGElement with these PRs:

Was the removal intentional? Should they be reintroduced?

Congratulations on this huge achievement!

Is this the right place to report issues?

I've noticed that the correspondingElement & correspondingUseElement properties have been removed from SVGElement with these PRs:

* [Migrate latest dom types into libdom.d.ts  TypeScript#44684](https://github.com/microsoft/TypeScript/pull/44684)

* [Update LKG to enable improved narrowing in 4.4. TypeScript#44842](https://github.com/microsoft/TypeScript/pull/44842)

Was the removal intentional? Should they be reintroduced?

Those are not available on any modern browser nor MDN, and thus are probably IE-specific properties. The removal is intended since the types library intends to only include things that exist in modern browsers.

@saschanaz Thank you for your quick response and explanation!

That makes sense. I was unable to find proper docs for these properties as well, except for the discontinued WebPlatform project.

I guess keeping them removed is most sensible. ๐Ÿ‘

Small note: it can be useful to have single @types/browser-common env - containing only objects shared in all browser environments. Therefore, typechecking can be used to ensure that library don't accidentally use globals accessible only in main thread.

Maybe I'm just doing it wrong, but I can't figure out a way of directly referencing individual types in the new @types/web package. It looks like basically the same file as lib.dom.d.ts that ships with Typescript, intended to be included with a triple-slash reference, and not using import type {...} from "web".

Is there a syntax that would allow me to import a single type? If not, would you consider packaging in such a way that this becomes possible? (I can open a new issue if that helps.)

I think a new issue will indeed be helpful ๐Ÿ‘

OK, I'll file one. Funny enough, I was looking for this to solve your own problem from 5 years ago. ETA: I filed #1207.

The reason it could be helpful for that TS issue (optional types) is that

// @ts-ignore
import type { Element } from "web";

would resolve to the correct type when @types/web is installed, and any if it isn't.

orta commented

I'm going to close this issue as "done" (it represents the work to deploy/run/maintain the separate @types/web infra)

There are separate issues +ideas for the splitting out types but that's not what this issue represents