-
-
Notifications
You must be signed in to change notification settings - Fork 218
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
Typescript definitions model a private Dom interface instead of using "the" public definitions from lib.dom.d.ts #1227
Comments
We can look into using the types from The question is why you are mixing the types. Either you should use the Happy DOM Window as the global scope and then you can use JSDOM doesn't have any types in the library, so my guess is that there are no types that can collide and Typescript will fallback on |
It would be nice to have compatible interfaces.
What exactly does this mean? Are the following patterns discouraged? import type { HTMLAudioElement } from "happy-dom";
let el: ReturnType<document.createElement>;
let link: typeof import("happy-dom").HTMLLinkElement; I am asking because I tried to get Compatibility in terms of call signatures would also be nice. For example, generic type arguments and type inference for // How should this be done when working with Happy DOM?
const anchor = d.querySelector("a");
const anchor = d.querySelector<HTMLAnchorElement>(".class-name"); Currently the following is what seems to be working in Happy DOM? // TS
const audio = document.querySelector("audio") as unknown as HTMLAudioElement | null; // JS
const audio = /** @type {HTMLAudioElement | null} */ (/** @type {unknown} */(document.querySelector("audio"))); Is this how it is supposed to work? It feels like, in a typed environment, one has to go through quite some effort to let the type system know that a query returns a clickable element (or null). |
It seems like What I meant is that if you import import { Window } from 'happy-dom';
const window = new Window(); Then it is not really correct to use If If you use both types they can collide when a variable name matches the global type (e.g. using the variable name document and then access properties on it). If you know a way which Happy DOM can import specific types from |
…"index.js", so that they are easier to import. The missing elements are HTMLAnchorElement, HTMLButtonElement, HTMLOptGroupElement, HTMLOptionElement, HTMLUnknownElement and HTMLSelectElement. Non-implemented element classes are now exporting HTMLElement as its name, so that is is also possible to import them.
…tions-model-a-private-dom-interface-instead-of-using-the-public-definitions-from-libdomdts #1227@patch: Adds missing element classes and types to the export in …
@valler You can read more about the release here: |
@capricorn86 amazing 🙂 About the follwoing:
That would be quite an undertaking? 🙄 Since TS is structural I'd guess one pretty much would have to work one's way up from the very bottom or look out for oppotunities to take some shortcuts, like Btw. I agree that mixing types is a bad idea or might cause problems. I think OP didn't raise the issue because the goal is to mix interfaces, but because there should be one interface definition for the DOM ( |
I believe that Happy DOM mostly matches However, I think the biggest problem is that we can't import This may not solve it if Happy DOM has newer functionality that doesn't exist in If developers wish to use |
Here's the catch:
Having compatible interfaces essentially boils down to something like in the following toy example. The implementation of the interface in JS may differ, but the interface definition should not be rewritten to remain compatible: // My Window for my own DOM
export class Window implements Window {} // Start implementing lib.dom.d.ts Window. |
It would be great if we could use the types from |
I gave // We need all the element types. Maybe this should go somewhere else and be imported into here
import type Element from '../element/Element.js';
import type HTMLElement from '../html-element/HTMLElement.js';
import type HTMLAnchorElement from '../html-anchor-element/HTMLAnchorElement.js';
// The list goes on ...
// The actual map
interface IHTMLElementTagNameMap {
a: HTMLAnchorElement;
abbr: HTMLElement;
address: HTMLElement;
// ... all of them
}
// Overloaded the signature with two additions
querySelector<K extends keyof IHTMLElementTagNameMap>(
selectors: K
): IHTMLElementTagNameMap[K] | null;
querySelector<E extends Element = Element>(selectors: string): E | null;
// Keep the existing signature in place
/**
* Query CSS Selector to find matching node.
*
* @param selector CSS selector.
* @returns Matching element.
*/
querySelector(selector: string): IElement | null; Added overloads together with the element map and the imports for the corresponding Happy DOM types needed by that map. It's not the only map, and I'd be happy to contribute. |
I am also getting this error:
|
@valler return types has been added for However, they return the interfaces and not the actual types. There is a plan to remove the interfaces for Nodes and replace circular dependencies with |
Happy DOM now returns the correct type for Interfaces for DOM related classes has also been removed (e.g. |
This is great news. |
Thank you @ShivamJoker! Just to clarify, this will not make Happy DOM fully compatible with mixing |
Using happy-dom with typescript libraries is very hard, because happy-dom element types are unrelated to the types used by typed dom-libraries, which refer to the HTMLElement, Element, ... types as defined in lib.dom.d.ts .
happy-dom should expose its elements as those public types (lib.dom.d.ts) .
I might be able to do this or help.
The text was updated successfully, but these errors were encountered: