-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Image class type in index.d.ts incompatible with HTMLImageElement #2197
Comments
The parts in the green would be wrong, as we always set If it used to build, that was deceptive. /// <reference lib="dom" />
import type {CanvasRenderingContext2d as NodeCanvasRenderingContext2D} from 'canvas';
function drawToContext(ctx: CanvasRenderingContext2d | NodeCanvasRenderingContext2D) {
// ...
} I'm not sure what you mean in the "steps to reproduce", because that code does pass type checking. If you have a more full example of code that's supposed to run in both browser and in node I might be able to help better. |
@chearon So I tried using this as you suggested: import type {CanvasRenderingContext2d as NodeCanvasRenderingContext2D} from 'canvas';
function drawToContext(ctx: CanvasRenderingContext2d | NodeCanvasRenderingContext2D) {
// ...
} However there is a problem in that NodeCanvas supplies "createCanvas" which the. documentation says should work on the frontend or the backend. This returns a the return type of |
I don't know how to interpret this since node-canvas can't be called in the browser. Your nodejs-only and browser-only code should get the context separately and pass to code that works with either browser or node-canvas. Can you post a minimal example? |
Oh, I see it now. I didn't know about |
@chearon The original design of NodeCanvas which worked for years is that you could use the NodeCanvas API both in the client and the server. In the client it provided a wrapper around the browser objects, and in the server it provided equivalent functionality. My application relies on this behaviour and recent changes to NodeCanvas that has broken these assumptions has caused me a lot of problems, that are in fact getting worse with each release of NodeCanvas now. Having said that, I would settle for anything that just worked at this point, but I have problems with Where for example "new Image" works in both browser and node, but produces different types, and then we somehow have to deal with two different types of context. It's the same with 'createCanvas'... Really I just want to know the current 'official' way to do this, so if I fix my code, it won't keep breaking on every release, like it has recently. |
I personally think that this is quite neat! (although I was the one who added it so I'm probably biased 😂) For the next major version I think that it would be nice if we specifically implemented With that said, this is just my personal opinion, and I haven't looked too much in to it to see how feasible it would be... I have also been working on an https://github.com/node-gfx/image Using these in the next major version of canvas (since the |
I can see why people like the We also risk re-introducing #1656 if we reference any DOM types at all in the node path. So we might have to delete the browser entry point in the next major version... @LinusU |
@chearon Another problem this is causing, is I used to be able to pass a CanvasRenderingContext2D from node-canvas to 'pdfjs' to render a PDF to it in Node (using TypeScript). This no longer works because pdfjs expects a browser 'CanvasRenderingContext2D'... and it appears the NodeCanvasRenderingContext2D is no longer compatible (cannot be passed as a CanvasRenderingContext2D in TypeScript (and would probably result in runtime errors in JavaScript?). I expect this will prevent many JS/TS libraries from being usable server-side, that used to work with node-canvas. |
Right. It would be an error to pass a node-canvas context where a browser context is expected since they are not the same. pdfjs could duck-type its argument to a subset of draw commands but we probably can't expect library authors to do that. You'll probably have to use |
@chearon That cast 'as' is not allowed because CanvasRenderingContext2D is not a subtype of NodeCanvasRendering2D. You have to do a two step cast like this:
Which is of course totally unsafe, context could be anything, and runtime errors become possible (but it does work for now). A base class for node-canvas that is the same as the browser CanvasRenderingContext2D, and then an extension for all the extra stuff in NodeCanvasRenderingContext2D would allow safe downcasting at least. |
I don't think this is possible while also providing accurate types. node-canvas lacks some standard things like |
I think so, as far as I remember they support everything that their browser equivalents does, and there is also support for getting the actual data out of them with an easy function.
Amazing 🤩 🤩
Let's do it! I've opened an issue 👉 #2232 |
Issue or Feature
Writing TypeScript code to run in both browser and backend has been broken with relatively recent changes.
In types/index.d.ts, the following changes are needed:
dataMode needs to be made optional, as it does not exist in the browser, and the types for
onload
andonerror
are incorrect.Steps to Reproduce
In the browser, 'new Image()' creates an HTMLImageElement, which cannot be passed to 'drawImage' because the Image type from node-canvas is incompatible.
Your Environment
[email protected]
[email protected]
6.1.8-gentoo-x86_64 #1 SMP PREEMPT_DYNAMIC Fri Jan 27 17:36:19 GMT 2023 x86_64 AMD Ryzen 9 5950X 16-Core Processor AuthenticAMD GNU/Linux
The text was updated successfully, but these errors were encountered: