Skip to content

Commit

Permalink
Merge pull request #162 from lowlighter/generic-qs
Browse files Browse the repository at this point in the history
feat: support generic typing for querySelector
  • Loading branch information
b-fuze authored May 5, 2024
2 parents 944ba6b + 34a7e34 commit 9121350
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/dom/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@ export class Document extends Node {
return doc;
}

querySelector(selectors: string): Element | null {
return this._nwapi.first(selectors, this);
querySelector<T = Element>(selectors: string): T | null {
return this._nwapi.first(selectors, this) as T;
}

querySelectorAll(selectors: string): NodeList {
querySelectorAll<T = Element>(selectors: string): NodeList<T> {
const nodeList = new NodeList();
const mutator = nodeList[nodeListMutatorSym]();

Expand Down
6 changes: 3 additions & 3 deletions src/dom/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -880,15 +880,15 @@ export class Element extends Node {
return elements[index - 1] ?? null;
}

querySelector(selectors: string): Element | null {
querySelector<T = Element>(selectors: string): T | null {
if (!this.ownerDocument) {
throw new Error("Element must have an owner document");
}

return this.ownerDocument!._nwapi.first(selectors, this);
return this.ownerDocument!._nwapi.first(selectors, this) as T;
}

querySelectorAll(selectors: string): NodeList {
querySelectorAll<T = Element>(selectors: string): NodeList<T> {
if (!this.ownerDocument) {
throw new Error("Element must have an owner document");
}
Expand Down
8 changes: 4 additions & 4 deletions src/dom/node-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ class NodeListMutatorImpl {
// its prototype and completely change its TypeScript-recognized type.
const NodeListClass: any = (() => {
// @ts-ignore
class NodeList extends Array<Node> {
class NodeList<T = Node> extends Array<T> {
forEach(
cb: (node: Node, index: number, nodeList: Node[]) => void,
cb: (node: T, index: number, nodeList: T[]) => void,
thisArg?: unknown,
) {
super.forEach(cb, thisArg);
}

item(index: number): Node | null {
item(index: number): T | null {
return this[index] ?? null;
}

Expand Down Expand Up @@ -192,7 +192,7 @@ for (
NodeListClass.prototype[instanceMethod] = undefined;
}

export interface NodeList {
export interface NodeList<T = Node> {
new (): NodeList;
readonly [index: number]: Node;
readonly length: number;
Expand Down
12 changes: 12 additions & 0 deletions test/units/querySelector-dom-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DOMParser } from "../../deno-dom-wasm.ts";
import type { HTMLTemplateElement } from "../../src/dom/elements/html-template-element.ts";

Deno.test("querySelector<T> and querySelectorAll<T> typings", () => {
const doc = new DOMParser().parseFromString(
`<template></template>`,
"text/html",
)!;

// We don't actually test anything here, we just challenge the TypeScript typings
doc.querySelector<HTMLTemplateElement>("template")!.content;
});

0 comments on commit 9121350

Please sign in to comment.