Skip to content

Commit

Permalink
fallback to HTMLElement for specific interfaces
Browse files Browse the repository at this point in the history
close #29
  • Loading branch information
g-plane committed Feb 21, 2023
1 parent 822d03a commit 4534a0c
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
32 changes: 32 additions & 0 deletions shim.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,36 @@ declare global {
interface Element {
closest<S extends string>(selector: S): ParseSelector<S> | null
}

interface HTMLElement {
querySelector<S extends string>(
selector: S,
): ParseSelector<S, HTMLElement> | null

querySelectorAll<S extends string>(
selector: S,
): NodeListOf<ParseSelector<S, HTMLElement>>

closest<S extends string>(selector: S): ParseSelector<S, HTMLElement> | null
}

interface Document {
querySelector<S extends string>(
selector: S,
): ParseSelector<S, HTMLElement> | null

querySelectorAll<S extends string>(
selector: S,
): NodeListOf<ParseSelector<S, HTMLElement>>
}

interface DocumentFragment {
querySelector<S extends string>(
selector: S,
): ParseSelector<S, HTMLElement> | null

querySelectorAll<S extends string>(
selector: S,
): NodeListOf<ParseSelector<S, HTMLElement>>
}
}
24 changes: 20 additions & 4 deletions shim.test.ts
Original file line number Diff line number Diff line change
@@ -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<Equal<typeof el, HTMLDivElement | HTMLSpanElement | null>>
type TestEl = Expect<
Equal<typeof htmlEl, HTMLDivElement | HTMLSpanElement | null>
>

const link = document.querySelector<HTMLAnchorElement>(prompt()!)
declare let selector: string
const link = document.querySelector<string, HTMLAnchorElement>(selector)
type TestLink = Expect<Equal<typeof link, HTMLAnchorElement | null>>

// @ts-expect-error
Expand All @@ -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<typeof closest, HTMLButtonElement | HTMLAnchorElement | null>
>

const unknownEl = document.querySelector('unknown')
type TestElement = Expect<Equal<typeof unknownEl, HTMLElement | null>>

declare let btn: HTMLButtonElement
const elementOfBtn = btn.querySelector('unknown')
type TestElementOfBtn = Expect<Equal<typeof elementOfBtn, HTMLElement | null>>

declare let element: Element
const elementOfElement = element.querySelector('unknown')
type TestElementOfElement = Expect<
Equal<typeof elementOfElement, Element | null>
>
52 changes: 52 additions & 0 deletions strict.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,56 @@ declare global {
selector: S,
): [E] extends [never] ? never : E | null
}

interface HTMLElement {
querySelector<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : E | null

querySelectorAll<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : NodeListOf<E>

closest<S extends string, E extends StrictlyParseSelector<S, HTMLElement>>(
selector: S,
): [E] extends [never] ? never : E | null
}

interface Document {
querySelector<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : E | null

querySelectorAll<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : NodeListOf<E>
}

interface DocumentFragment {
querySelector<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : E | null

querySelectorAll<
S extends string,
E extends StrictlyParseSelector<S, HTMLElement>,
>(
selector: S,
): [E] extends [never] ? never : NodeListOf<E>
}
}
36 changes: 22 additions & 14 deletions strict.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Equal<typeof e1, Element | null>>,
Expect<Equal<typeof e2, Element | null>>,
Expect<Equal<typeof e3, Element | null>>,
Expect<Equal<typeof e4, Element | null>>,
Expect<Equal<typeof e1, HTMLElement | null>>,
Expect<Equal<typeof e2, HTMLElement | null>>,
Expect<Equal<typeof e3, HTMLElement | null>>,
Expect<Equal<typeof e4, HTMLElement | null>>,
Expect<Equal<typeof e5, never>>,
Expect<Equal<typeof e6, never>>,
Expect<Equal<typeof e7, never>>,
Expect<Equal<typeof e8, never>>,
Expect<Equal<typeof e9, Element | null>>,
Expect<Equal<typeof e10, Element | null>>,
Expect<Equal<typeof e9, HTMLElement | null>>,
Expect<Equal<typeof e10, HTMLElement | null>>,
Expect<Equal<typeof e11, never>>,
Expect<Equal<typeof e12, never>>,
Expect<Equal<typeof e13, never>>,
Expand All @@ -60,24 +66,26 @@ type Tests = [
Expect<Equal<typeof e16, HTMLDivElement | null>>,
Expect<Equal<typeof e17, HTMLSpanElement | null>>,
Expect<Equal<typeof e18, never>>,
Expect<Equal<typeof e19, Element | null>>,
Expect<Equal<typeof e19, HTMLElement | null>>,
Expect<Equal<typeof e20, never>>,
Expect<Equal<typeof e21, Element | null>>,
Expect<Equal<typeof e22, Element | null>>,
Expect<Equal<typeof e23, Element | null>>,
Expect<Equal<typeof e24, Element | null>>,
Expect<Equal<typeof e25, Element | null>>,
Expect<Equal<typeof e21, HTMLElement | null>>,
Expect<Equal<typeof e22, HTMLElement | null>>,
Expect<Equal<typeof e23, HTMLElement | null>>,
Expect<Equal<typeof e24, HTMLElement | null>>,
Expect<Equal<typeof e25, HTMLElement | null>>,
Expect<Equal<typeof e26, never>>,
Expect<Equal<typeof e27, never>>,
Expect<Equal<typeof e28, HTMLDivElement | HTMLSpanElement | null>>,
Expect<Equal<typeof e29, never>>,
Expect<Equal<typeof e30, never>>,
Expect<Equal<typeof e31, never>>,
Expect<Equal<typeof e32, HTMLDivElement | Element | null>>,
Expect<Equal<typeof e32, HTMLDivElement | HTMLElement | null>>,
Expect<Equal<typeof e33, never>>,
Expect<Equal<typeof e34, never>>,
Expect<Equal<typeof e35, HTMLAnchorElement | null>>,
Expect<Equal<typeof e36, Element | null>>,
Expect<Equal<typeof e36, HTMLElement | null>>,
Expect<Equal<typeof e37, Element | null>>,
Expect<Equal<typeof e38, HTMLElement | null>>,
]

// @ts-expect-error
Expand Down

0 comments on commit 4534a0c

Please sign in to comment.