microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.16k stars 12.51k forks source link

HTMLCanvasElement.transferControlToOffscreen() removed from lib.dom.d.ts #45745

Closed jamespearce2006 closed 3 years ago

jamespearce2006 commented 3 years ago

Bug Report

A recent change to lib.dom.d.ts has removed the HTMLCanvasElement.transferControlToOffscreen() method. Attempting to use this method now generates an error.

Even though not all browsers currently support offscreen canvases, checking for the existence of the method on the prototype is a good way of detecting whether offscreen canvases are supported. Eg:

    private get supportsOffscreenCanvas(): boolean {
        return HTMLCanvasElement.prototype.transferControlToOffscreen !== undefined;
    }

This now generates an error by the Typescript compiler, as transferControlToOffscreen is no longer defined in the type definitions.

🔎 Search Terms

lib.dom.d.ts HTMLCanvasElement transferControlToOffscreen

🕗 Version & Regression Information

This issue was introduced in the latest version of VS Code, which is using Typescript 4.4.2. The issue was introduced with this PR: https://github.com/microsoft/TypeScript/pull/44842

💻 Code

Attempting to reference the method transferControlToOffscreen() on HTMLCanvasElement generates errors.

   let offscreenCanvas = canvas.transferControlToOffscreen();

🙁 Actual behavior

This generates an error because the method was removed from the DOM type definitions in the above referenced PR.

🙂 Expected behavior

I'd expect this not to generate an error, and continue to work as it did before.

MartinJohns commented 3 years ago

Even though not all browsers currently support offscreen canvases, checking for the existence of the method on the prototype is a good way of detecting whether offscreen canvases are supported.

Having experimental functions with bad support in the standard library is something TypeScript usually does not do. It leads to users using these functions without being aware of their experimental unsupported status.

Removal of this function seems to be intended as per microsoft/TypeScript-DOM-lib-generator#1029:

The 4.4 dom.d.ts file which is included with TypeScript includes quite a lot of changes, with a lot of APIs which have been marked as deleted by the web standards committees.

If you depend on this you can use declaration merging to provide your own type definition for this function.

jamespearce2006 commented 3 years ago

Having experimental functions with bad support...

It's experimental, but it's certainly not marked as deleted, and it has good support in Chromium browsers, and flagged support in Firefox. Other, upcoming APIs depend on offscreen canvases (like WebCodecs), so it seems strange to unilaterally remove it at this point.

Furthermore, it's been in the type definition for a while - I see no logic in removing it now, and thus breaking the increasing amount of stuff that depends on it.

jamespearce2006 commented 3 years ago

Also, I notice that lib.dom.d.ts still has the definition for OffscreenCanvas in it. So, the decision to remove "transferControlToOffscreen" is inconsistent.

Edit - no, I'm wrong. OffscreenCanvas isn't there in the latest version. (Juggling too many versions of lib.dom.d.ts)

beauxq commented 3 years ago

Is there any way to merge OffscreenCanvas into CanvasImageSource, so that in my project CanvasImageSource includes OffscreenCanvas?

It looks really bad to say CanvasImageSource | OffscreenCanvas because OffscreenCanvas is a CanvasImageSource.

It's like saying "mammals or cats". It's redundant.

typescript-bot commented 3 years ago

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

steno916 commented 3 years ago

How is this working as intended? You broke peoples code!

andrewbranch commented 3 years ago

It’s not intentional that it was ever included in the first place, as it doesn’t meet our bar of spec/support for standard lib inclusion. The removal was documented ahead of time as @MartinJohns pointed out. We’re aware that 4.4 included more lib breaks than usual as we transitioned to a new process for generating them, and while we expect that the breakiness of 4.4 was a one-time pain associated with that transition, we’re having conversations about how we can do better with this in the future. That’s part of the motivation for a versioned @types/web (https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1023) and potentially other ways of versioning and resolving libs (#45685)—in general, we don’t think it makes sense for people to be stuck dealing with lib changes (particularly DOM lib changes) if they want to upgrade their TS version.

trusktr commented 3 years ago

Well, I guess the TS team hasn't learned how to use semver yet, the versioning standard that the vast majority of their own community uses.

trusktr commented 3 years ago

in general, we don’t think it makes sense for people to be stuck dealing with lib changes (particularly DOM lib changes) if they want to upgrade their TS version.

If that were true, then why didn't you release TS v5 instead? Why didn't you keep the APIs and add a new @experimental decorator to cause these APIs to be crossed out or marked with caution icons in IDEs? There are better solutions than willfully breaking apps.

trusktr commented 3 years ago

Do you know what's really annoying? When type errors (due to these lib.dom changes) start happening inside 3rd-party libs in your project's node_modules, and you know someone did it to you on purpose.

MartinJohns commented 3 years ago

If that were true, then why didn't you release TS v5 instead?

That would have made exactly no difference. TypeScript does not follow SemVer, for good reasons. Pretty much every TypeScript release contains breaking changes.

andrewbranch commented 3 years ago

@trusktr https://github.com/microsoft/TypeScript/issues/14116 😑

FWIW, decoupling your lib versions is now possible in 4.5 with https://github.com/microsoft/TypeScript/pull/45771.

Any further comments on this issue will be about HTMLCanvasElement.transferControlToOffscreen(); otherwise I will be forced to reply with snarky and exasperated GIFs, or just lock the issue as off-topic, depending on how I’m feeling in the moment.

caffed commented 2 years ago

Slightly inconvenient, but I am just using // @ts-ignore anywhere I use this method.

  // @ts-ignore
  const offscreen = renderer.domElement.transferControlToOffscreen();