From 4534a0c8aa052210863ef5ed3e63a6b7dd4e106c Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Tue, 21 Feb 2023 14:13:18 +0800 Subject: [PATCH] fallback to `HTMLElement` for specific interfaces close #29 --- CHANGELOG.md | 1 + shim.d.ts | 32 +++++++++++++++++++++++++++++++ shim.test.ts | 24 +++++++++++++++++++---- strict.d.ts | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ strict.test.ts | 36 ++++++++++++++++++++-------------- 5 files changed, 127 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f818703..2a7e8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Added fallback support to strict parser. +- Fallback to `HTMLElement` for `HTMLElement`, `Document` and `DocumentFragment`. (Close [#29](https://github.com/g-plane/typed-query-selector/issues/29)) ## v2.8.1 diff --git a/shim.d.ts b/shim.d.ts index 2a6f553..9b21fcb 100644 --- a/shim.d.ts +++ b/shim.d.ts @@ -12,4 +12,36 @@ declare global { interface Element { closest(selector: S): ParseSelector | null } + + interface HTMLElement { + querySelector( + selector: S, + ): ParseSelector | null + + querySelectorAll( + selector: S, + ): NodeListOf> + + closest(selector: S): ParseSelector | null + } + + interface Document { + querySelector( + selector: S, + ): ParseSelector | null + + querySelectorAll( + selector: S, + ): NodeListOf> + } + + interface DocumentFragment { + querySelector( + selector: S, + ): ParseSelector | null + + querySelectorAll( + selector: S, + ): NodeListOf> + } } diff --git a/shim.test.ts b/shim.test.ts index 442c1c3..870a5b4 100644 --- a/shim.test.ts +++ b/shim.test.ts @@ -1,12 +1,15 @@ import './shim' import type { Equal, Expect } from '@type-challenges/utils' -const el = document.querySelector( +const htmlEl = document.querySelector( '.container > #sign-up-form > div#notice, span.tip', ) -type TestEl = Expect> +type TestEl = Expect< + Equal +> -const link = document.querySelector(prompt()!) +declare let selector: string +const link = document.querySelector(selector) type TestLink = Expect> // @ts-expect-error @@ -20,7 +23,20 @@ results.push(document.querySelector('div')) // @ts-expect-error results.push(document.querySelector('div#app')) -const closest = el!.closest('button.btn-confirm, a.link') +const closest = htmlEl!.closest('button.btn-confirm, a.link') type TestClosest = Expect< Equal > + +const unknownEl = document.querySelector('unknown') +type TestElement = Expect> + +declare let btn: HTMLButtonElement +const elementOfBtn = btn.querySelector('unknown') +type TestElementOfBtn = Expect> + +declare let element: Element +const elementOfElement = element.querySelector('unknown') +type TestElementOfElement = Expect< + Equal +> diff --git a/strict.d.ts b/strict.d.ts index 200bfdd..02b3b3c 100644 --- a/strict.d.ts +++ b/strict.d.ts @@ -16,4 +16,56 @@ declare global { selector: S, ): [E] extends [never] ? never : E | null } + + interface HTMLElement { + querySelector< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : E | null + + querySelectorAll< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : NodeListOf + + closest>( + selector: S, + ): [E] extends [never] ? never : E | null + } + + interface Document { + querySelector< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : E | null + + querySelectorAll< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : NodeListOf + } + + interface DocumentFragment { + querySelector< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : E | null + + querySelectorAll< + S extends string, + E extends StrictlyParseSelector, + >( + selector: S, + ): [E] extends [never] ? never : NodeListOf + } } diff --git a/strict.test.ts b/strict.test.ts index 57f7b4d..42942db 100644 --- a/strict.test.ts +++ b/strict.test.ts @@ -41,17 +41,23 @@ let variableSelector = 'p a.lnk' const e35 = document.querySelector(`${constantSelector}`) const e36 = document.querySelector(`${variableSelector}`) +declare let element: Element +const e37 = element.querySelector('unknown') + +declare let btn: HTMLButtonElement +const e38 = btn.querySelector('unknown') + type Tests = [ - Expect>, - Expect>, - Expect>, - Expect>, + Expect>, + Expect>, + Expect>, + Expect>, Expect>, Expect>, Expect>, Expect>, - Expect>, - Expect>, + Expect>, + Expect>, Expect>, Expect>, Expect>, @@ -60,24 +66,26 @@ type Tests = [ Expect>, Expect>, Expect>, - Expect>, + Expect>, Expect>, - Expect>, - Expect>, - Expect>, - Expect>, - Expect>, + Expect>, + Expect>, + Expect>, + Expect>, + Expect>, Expect>, Expect>, Expect>, Expect>, Expect>, Expect>, - Expect>, + Expect>, Expect>, Expect>, Expect>, - Expect>, + Expect>, + Expect>, + Expect>, ] // @ts-expect-error