DOM Lib Generator infra thread
orta opened this issue ยท 19 comments
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:
-
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. #1025Because 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. #885Unsure 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.) -
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.ts
files, 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.
- 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...
- Not sure what name webxr-specific package would have in this case.
- 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
.
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 ๐
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.
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
So far, we have:
- A PR to TypeScript adding types_web as the default dom.d.ts
- Shipped
@types/web
0.0.1 which representsTypeScript-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
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 fromSVGElement
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.
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