microsoft / TypeScript-DOM-lib-generator

Tool for generating dom related TypeScript and JavaScript library files
Apache License 2.0
622 stars 421 forks source link

TypeScript 4.4 libdom changes #1029

Closed orta closed 2 months ago

orta commented 3 years ago

Beta

With TypeScript 4.4, we coordinated some pretty fundamental infrastructure work to prepare for the version of dom.d.ts with the future of the generator repo. This work resulted in two note-worthy items:

We plan to have thorough support for replacing lib.dom.d.ts with @types/web in 4.5 with https://github.com/microsoft/TypeScript/issues/44795

orta commented 3 years ago

High Level Changes from 4.3 to 4.4

dom.d.ts

New interfaces

Removed interfaces

Modified

Non-value types

index.iterable.d.ts

Non-value types

h-joo commented 3 years ago

The following four types also seems to be removed, but are not mentioned in the above list :

orta commented 3 years ago

@types/web@0.0.16 should be the version which is shipped with TS 4.4rc

Jack-Works commented 3 years ago

Found undocumented breaking change: PermissionName has less union members than 4.3 which cause the following code type error.

navigator.permissions.query({ name: 'camera' })

See: https://w3c.github.io/permissions/#enumdef-permissionname

Jack-Works commented 3 years ago

Breaking change documented wrong:

CryptoKeyPair didn't get removed.

// 4.3
interface CryptoKeyPair {
    privateKey: CryptoKey;
    publicKey: CryptoKey;
}
// 4.4
interface CryptoKeyPair {
    privateKey?: CryptoKey;
    publicKey?: CryptoKey;
}
Jack-Works commented 3 years ago

ClipboardItem constructor type is wrong. According to MDN, it should be string | Blob | Promise<string | Blob>.

In 4.3 it is string | Blob, in 4.4 it is Promise<string | Blob> which is wrong.

saschanaz commented 3 years ago

Found undocumented breaking change: PermissionName has less union members than 4.3 which cause the following code type error.

navigator.permissions.query({ name: 'camera' })

See: https://w3c.github.io/permissions/#enumdef-permissionname

Camera permission is at risk because of lack of multiple implementation, so I guess the work item is to document the removal.

ClipboardItem constructor type is wrong. According to MDN, it should be string | Blob | Promise<string | Blob>.

In 4.3 it is string | Blob, in 4.4 it is Promise<string | Blob> which is wrong.

1102

HolgerJeromin commented 3 years ago

I want to add (deprecated: ref #884) mouseWheelEvent to the list of removed types

busches commented 3 years ago

Undocumented change msSaveBlob was removed from window.navigator in TypeScript 4.4.2.

IceCreamYou commented 3 years ago

I tried upgrading from TS 4.3.5 to 4.4.2 today and encountered two issues:

  1. HTMLDialogElement went missing (as a value, not as a type). This is noted in the list above. But why? It's supported by Chrome, Edge, and Opera, and by Firefox behind a flag. The type is still present, as it is needed to represent <dialog> elements. I can write declare var HTMLDialogElement: HTMLDialogElement; to allow using it as a value, but then element instanceof HTMLDialogElement no longer works as a type guard.
  2. HTMLInputElement.autofocus was removed. This is not noted in the list above. This seems like a bug since it is supported in every browser. The MDN page's browser compatibility section just refers to the page for the global autofocus attribute where it is noted as fully supported in Chrome, Edge, and Opera, and supported everywhere on several elements including HTMLInputElement. In my case, I have a custom JSX implementation, and I basically have to patch the HTMLInputElement type to work around this.

It would be great if these changes could be reverted.

saschanaz commented 3 years ago
  1. HTMLDialogElement went missing (as a value, not as a type). This is noted in the list above. But why? It's supported by Chrome, Edge, and Opera, and by Firefox behind a flag. The type is still present, as it is needed to represent <dialog> elements. I can write declare var HTMLDialogElement: HTMLDialogElement; to allow using it as a value, but then element instanceof HTMLDialogElement no longer works as a type guard.

Chrome/Edge/Opera all uses the same engine Blink and no other engine supports it without a flag, that is why. Please refer to https://github.com/microsoft/TypeScript-DOM-lib-generator#when-the-type-is-missing for the reasoning here.

  1. HTMLInputElement.autofocus was removed. This is not noted in the list above. This seems like a bug since it is supported in every browser. The MDN page's browser compatibility section just refers to the page for the global autofocus attribute where it is noted as fully supported in Chrome, Edge, and Opera, and supported everywhere on several elements including HTMLInputElement. In my case, I have a custom JSX implementation, and I basically have to patch the HTMLInputElement type to work around this.

Fixed by #1111

IceCreamYou commented 3 years ago

Thanks, I read that section of the README but it's not clear about flagged features, plus <dialog> is enabled by default in Firefox Nightly.

Juraj-Masiar commented 3 years ago

Why was hashchange event removed? Now there is only Event which doesn't have newURL property: https://www.typescriptlang.org/play?ts=4.4.2#code/O4SwdgJg9sB0CGEIFEBuBTMAXAMiAzlpugE4AUA5ABbz5UDGNYA5uhQDQAEZ6AXJwAlaVAMJNWaTFgCUnALwA+TgG90sMOmABVAEo4AvtKA

saschanaz commented 3 years ago

Why was hashchange event removed? Now there is only Event which doesn't have newURL property: https://www.typescriptlang.org/play?ts=4.4.2#code/O4SwdgJg9sB0CGEIFEBuBTMAXAMiAzlpugE4AUA5ABbz5UDGNYA5uhQDQAEZ6AXJwAlaVAMJNWaTFgCUnALwA+TgG90sMOmABVAEo4AvtKA

Fixed by #1104

kindlich commented 3 years ago

Location#reload(forcedReload: boolean): void was removed as well. Was that intended?

saschanaz commented 3 years ago

Location#reload(forcedReload: boolean): void was removed as well. Was that intended?

It's currently a Firefox specific extension, so yes, that was intended.

icepower03 commented 3 years ago

Hello, speech recognition apis have been removed but i don't find informations about deprecation of this technology.

is there a remplacement api ?

saschanaz commented 3 years ago

Hello, speech recognition apis have been removed but i don't find informations about deprecation of this technology.

is there a remplacement api ?

It's not deprecated, it's just not mature enough with no prefix-less implementation and being still in WICG (where immature specifications exist).

daggmano commented 3 years ago

Just a query, maybe my bad understanding, but File.webkitRelativePath is not a standard property and, according to MDN, should NOT be used on production sites. Can this be made optional or removed (or is my understanding here wrong)? https://developer.mozilla.org/en-US/docs/Web/API/File/webkitRelativePath

pbadenski commented 3 years ago

I believe ClipboardItem constructor should be restricted to only accept Blob. Blink has only partial support for ClipboardItem - as per MDN:

The ClipboardItem constructor only accepts a blob as the item data, but not strings or Promises that resolve to strings or blobs. See bug 1014310.

saschanaz commented 3 years ago

I believe ClipboardItem constructor should be restricted to only accept Blob. Blink has only partial support for ClipboardItem - as per MDN:

The ClipboardItem constructor only accepts a blob as the item data, but not strings or Promises that resolve to strings or blobs. See bug 1014310.

Makes sense, do you want to write a patch?

dhaigh commented 3 years ago

sorry for the noob question: how is it decided which interfaces get added or removed? at what point do changes usually end up in microsoft/TypeScript?

the new TS features are great, but sadly all the dom type changes are a bit of a disincentive to upgrade for me at the moment. for example, some code that I work on uses RTCSctpTransport which is still in the spec, has no "feature at risk" annotation, and still works in chrome :/

nonetheless thanks for all the great work.

saschanaz commented 3 years ago

Mostly based on MDN browser compatibility data. For example, RTCSctpTransport is marked as Chrome(ium)-only on MDN: https://developer.mozilla.org/en-US/docs/Web/API/RTCSctpTransport#browser_compatibility

TimvdLippe commented 3 years ago

FYI at Chrome DevTools we have started our attempts to upgrade to TypeScript 4.4.2, but sadly this issue is one the major timesinks for this release. Initial big hitters are:

Unfortunately, adding @types/web isn't as straightforward for us and also does not appear to resolve the situation for us where we rely on Chromium-only API's. That said, Chrome DevTools is probably in a special situation where we run on a single engine, so sometimes we use modern API's that are not supported on other engines just yet.

It seems like our Google internal team ran into similar issues before: https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1067 But since we use a different stack and upgrade TypeScript at our own pace, we ran into this later than them.

mrttrifork commented 3 years ago

I think the correct approach would be to add @deprecated with an explanation to the functions or properties that will be removed in the next major release. With this approach, developers will be able to see that object.deprecated is going to be removed and can raise their concerns before the removal happens.

With the current approach, you need won't realize that a change is coming if you are not actively using the beta or RC version of TypeScript, because in 4.3 the function exists and in 4.4 the function is gone.

saschanaz commented 3 years ago

4.4 was a special release that trimmed a lot of nonstandard things, I think any future releases will follow W3C/WHATWG deprecation step.

berickson1 commented 3 years ago

The removal of autoGainControl and noiseSuppression caused a build break. This is supported in most browsers and outlined in W3C Capture Streams - https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksupportedconstraints-autogaincontrol Can you provide any insight into why it was removed?

dylancrockett commented 3 years ago

The removal of the userVisibleOnly property from the PushSubscriptionOptions interface caused issues in a project where WebPush is being used. Chrome & Edge still require userVisibleOnly to be set when calling PushManager.subscribe() or the call will fail. userVisibleOnly is also still documented in the latest W3C Push API Draft: https://www.w3.org/TR/push-api/#pushsubscriptionoptions-interface. Is there a reason why this property was removed?

saschanaz commented 3 years ago

The removal of autoGainControl and noiseSuppression caused a build break. This is supported in most browsers and outlined in W3C Capture Streams - https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksupportedconstraints-autogaincontrol Can you provide any insight into why it was removed?

Seems they are supported on Firefox and Chrome. PR welcome.

userVisibleOnly is also still documented in the latest W3C Push API Draft: https://www.w3.org/TR/push-api/#pushsubscriptionoptions-interface. Is there a reason why this property was removed?

Yes: https://github.com/microsoft/TypeScript-DOM-lib-generator#why-is-my-fancy-api-still-not-available-here

See MDN for the data. Note that PushSubscrptionOptionsInit still has userVisibleOnly so the option still can be set. (Logically it shouldn't exist either but there is no good way to autodetect dictionary member support.)

ova2 commented 3 years ago

Why did you remove OffscreenCanvas? It is available in Edge, Chrome and Opera.

orta commented 3 years ago

Those are all chromium, and collectively only count as one browser implementation

ova2 commented 3 years ago

@orta Well, but if all browsers would be chromium based, they would be count as one and we would have nothing at all :-) I think, other criteria such as usage in %, global diffusion,... would be more correct.

JirkaDellOro commented 3 years ago

Thanks, I read that section of the README but it's not clear about flagged features, plus <dialog> is enabled by default in Firefox Nightly.

I also think that the tag deprecated is quite misleading, since it is an upcoming feature which is about to be supported. As @IceCreamYou stated, it is already also by the nightly build of Firefox.

Since I'm working with electron, which uses chromium, it would be helpful to have the dom.d.ts for chrome. Is that available and how?

orta commented 3 years ago

Well, but if all browsers would be chromium based

C'mon, you know that's not true. Let's be realistic here, we'd not be working to the idea of web standards if we pretend that the only things which matter are Google's choices of how it runs its browser. There are three major browsers, and using consensus between them is a good strategy for deciding if something is adopted for the long-term.

it would be helpful to have the dom.d.ts for chrome

You're welcome to build a version of the dom.d.ts for just chromium, the upcoming TypeScript 4.5 include a feature which allows folks to switch out that with their own version https://github.com/microsoft/TypeScript/issues/44795 which makes that much easier to set up, though it would be possible to do today - you'd probably want to fork this repo and start from there. You can mix it with browser-compat-data to determine what is available.

jakub-g commented 3 years ago

Small remark about the new NetworkInformation interface from my side: it contains only .type, but not .effectiveType nor other fields. Based on MDN data, .effectiveType support level is similar to .type: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation#browser_compatibility

saschanaz commented 3 years ago

Small remark about the new NetworkInformation interface from my side: it contains only .type, but not .effectiveType nor other fields. Based on MDN data, .effectiveType support level is similar to .type: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation#browser_compatibility

Good catch, PR welcome.

justinfagnani commented 3 years ago

Why were elementFromPoint, elementsFromPoint removed from DocumentOrShadowRoot? These exist on ShadowRoot and weren't added to it, so compilation breaks now when using them.

saschanaz commented 3 years ago

Why were elementFromPoint, elementsFromPoint removed from DocumentOrShadowRoot? These exist on ShadowRoot and weren't added to it, so compilation breaks now when using them.

1123 fixed it. (The spec defines as such but that doesn't reflect the reality, as the comment in that PR says)

justinfagnani commented 3 years ago

@saschanaz thanks! Has that fix made it into typescript@next?

saschanaz commented 3 years ago

Nah, but you can try it today by installing @types/web from npm! (Please read the guide in that page to deploy it)

trusktr commented 3 years ago

Why don't ya'll add an @experimental tag that is similar to @deprecated and not break apps? Does the TS team know how annoying in-range breaks are?

JirkaDellOro commented 3 years ago

add an @experimental tag that is similar to @deprecated and not break apps

Great suggestion! It's really bad when TypeScript suggests you're working with outdated technology, when you are actually using upcoming ones.

dobesv commented 3 years ago

Any references as to why InputDeviceInfo is deleted? It isn't marked deprecated or deleted on MDN:

https://developer.mozilla.org/en-US/docs/Web/API/InputDeviceInfo

saschanaz commented 3 years ago

That's because the previous version of BCD marked it as unsupported. https://github.com/mdn/browser-compat-data/pull/12451 fixed it, so it will also be fixed soon here. Thanks @queengooborg 👍

JeremyTCD commented 3 years ago

The removal of OffscreenCanvas and associated symbols broke my project, so I tried declaration merging.

I had issues though. This is my custom offscreenCanvas.d.ts , extracted from a 4.3.* lib.dom.d.ts (errors denoted by comments):

/// <reference lib="dom" />

interface HTMLCanvasElement extends HTMLElement {
    transferControlToOffscreen(): OffscreenCanvas;
}

interface ImageBitmapRenderingContext {
    // Error: Subsequent property declarations must have the same type.  Property 'canvas' must be of type 'HTMLCanvasElement', but here has type 'HTMLCanvasElement | OffscreenCanvas'.
    readonly canvas: HTMLCanvasElement | OffscreenCanvas;
}

interface WebGLRenderingContextBase {
    // Error: Subsequent property declarations must have the same type.  Property 'canvas' must be of type 'HTMLCanvasElement'
    readonly canvas: HTMLCanvasElement | OffscreenCanvas;
}

interface OffscreenCanvas extends EventTarget {
    height: number;
    width: number;
    // Error: Cannot find name 'ImageEncodeOptions'
    convertToBlob(options?: ImageEncodeOptions): Promise<Blob>;
    getContext(contextId: "2d", options?: CanvasRenderingContext2DSettings): OffscreenCanvasRenderingContext2D | null;
    getContext(contextId: "bitmaprenderer", options?: ImageBitmapRenderingContextSettings): ImageBitmapRenderingContext | null;
    getContext(contextId: "webgl", options?: WebGLContextAttributes): WebGLRenderingContext | null;
    getContext(contextId: "webgl2", options?: WebGLContextAttributes): WebGL2RenderingContext | null;
    getContext(contextId: OffscreenRenderingContextId, options?: any): OffscreenRenderingContext | null;
    transferToImageBitmap(): ImageBitmap;
}

declare var OffscreenCanvas: {
    prototype: OffscreenCanvas;
    new(width: number, height: number): OffscreenCanvas;
};

interface OffscreenCanvasRenderingContext2D extends CanvasCompositing, CanvasDrawImage, CanvasDrawPath, CanvasFillStrokeStyles, CanvasFilters, CanvasImageData, CanvasImageSmoothing, CanvasPath, CanvasPathDrawingStyles, CanvasRect, CanvasShadowStyles, CanvasState, CanvasText, CanvasTextDrawingStyles, CanvasTransform {
    readonly canvas: OffscreenCanvas;
    commit(): void;
}

declare var OffscreenCanvasRenderingContext2D: {
    prototype: OffscreenCanvasRenderingContext2D;
    new(): OffscreenCanvasRenderingContext2D;
};

type OffscreenRenderingContextId = "2d" | "bitmaprenderer" | "webgl" | "webgl2";
type OffscreenRenderingContext = OffscreenCanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext;
// Error: Duplicate identifier 'CanvasImageSource '.
type CanvasImageSource = HTMLOrSVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas;
// Error: Duplicate identifier 'TexImageSource '.
type TexImageSource = ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | OffscreenCanvas;
// Error: Duplicate identifier 'Transferable'.
type Transferable = ArrayBuffer | MessagePort | ImageBitmap | OffscreenCanvas;

I get that the errors are to-be-expected. What I'm curious about is how or if they can be worked around - am I missing something with declaration merging? If not, what should projects using experimental symbols that cannot be added using declaration merging do? Is hand editing lib.dom.d.ts the way to go?

ova2 commented 3 years ago

@JeremyTCD Just use my declarations from DefinitlyTyped https://www.npmjs.com/package/@types/offscreencanvas

JeremyTCD commented 3 years ago

@ova2 After installing I still had errors because of type usage in my code, e.g. Transferable arguments. But I got the gist of how to work around these issues from your typings.

Instead of trying to overload types, e.g:

type Transferable = ArrayBuffer | MessagePort | ImageBitmap | OffscreenCanvas;

I should've been looking for usages of types and replacing them with union types, e.g. Transferable > Transferable | OffscreenCanvas.

Thanks for the tip!

JirkaDellOro commented 3 years ago

It's strongly misleading to mark experimental technologies, which I want to use to be in the front line, as @deprecated, which is the opposite from this perspective. Instead, @experimental would be helpful and highly appreciated!

orta commented 3 years ago

Yeah, we're not planning on marking APIs which haven't got to the point of being supported in many browsers with @deprecated - they're just not meant to be in the DOM types shipped with TypeScript

The idea of using @experimental is cool, but that also means shipping definitions which are ahead of their time which we shouldn't do IMO. That's what DefinitelyTyped is for.

JirkaDellOro commented 3 years ago

The size of this thread actually suggests that many people are irritated, that their applications suddenly appear buggy. And now we are forced to resort to solutions that feel like workarounds. I'd actually appreciate it a lot if the standard typescript packages would allow me to use upcoming technologies and simply hint about.

Isn't that one of the great features of TypeScript that we can use the standards of tomorrow already today?