๐ช A TypeScript-types patch for querySelector()
/ querySelectorAll()
, make them return types you expect them to! ๐ฎ
- ๐ง Smart IntelliSense - autoโsuggests valid
CSS selectors
and infers exact element types - ๐ Works with literal selector strings to power IntelliSense
- ๐ช Typeโdriven safety - catches invalid selectors at compile time in TypeScript
- ๐ท Tag name mapping - resolves HTML tag names to their correct HTMLElement types
- ๐ฏ Selector parsing - supports
tag
,class
,ID
, andattribute
selectors in type space - ๐ Combinator awareness - understands
descendant
,child
,sibling
, andcolumn combinators
- ๐ฑ Pseudoโclass support - recognizes
:root
and maps it to the<html>
element type - ๐ Global augmentation - extends
Document
andElement
to return precise types forquerySelector
/querySelectorAll
- โก Zero runtime cost - all logic is purely in TypeScript types, no JS overhead
Install it by executing any of the following, depending on your preferred package manager:
pnpm add @igorskyflyer/magic-queryselector
yarn add @igorskyflyer/magic-queryselector
npm i @igorskyflyer/magic-queryselector
Here's magic-querySelector
in action.
without-magic.mp4
magic-queryselector
with-magic.mp4
magic-queryselector
Visual Studio Code theme used in the demonstration isKai ๐
.
Including the magic-queryselector
into your project depends on the language of it. Please see the appropriate section for your project:
If you want to use it with TypeScript, you need to import this module. This augments the global Document
and Element
interfaces so querySelector()
and querySelectorAll()
return the correct element type based on your selector.
To do so, copy the following code:
import '@igorskyflyer/magic-queryselector'
and then do one of the either options:
[ 1st option ]
This method requires a valid
tsconfig.json
file to be present in the root of your project.
Create a magic.d.ts
file in the root directory of your project and add the snippet you copied:
magic.d.ts
import '@igorskyflyer/magic-queryselector'
That's it! You're all set up. ๐ฅณ
TypeScript's language server sometimes likes to play games, if the patch doesn't work immediately please restart TypeScript language server or Visual Studio Code.
[ 2nd option ]
Add the code snippet you copied to the top of your entrypoint/main TypeScript file.
index.ts
import '@igorskyflyer/magic-queryselector'
TypeScript's language server sometimes likes to play games, if the patch doesn't work immediately please restart TypeScript language server or Visual Studio Code.
If you want to use it with JavaScript, you don't need to do anything besides installing the package.
TypeScript's language server sometimes likes to play games, if the patch doesn't work immediately please restart TypeScript language server or Visual Studio Code.
This patch extends the default (return) type inference of TypeScript by inferring the types from the input string
containing selectors/combinators passed to querySelector()
/ querySelectorAll()
.
querySelector()
will return the type listed in the table below, e.g.HTMLDivElement
, whilequerySelectorAll()
will returnNodeListOf<T>
of the same type, e.g.NodeListOf<HTMLDivElement>
.Unsupported or unrecognised selectors will gracefully fall back to the generic
HTMLElement
type, ensuring your code still typeโchecks while signalling that no specific element type could be inferred.For brevity this table only shows the types for
querySelector()
.Read more about selector structure
and selectors and combinators
on
MDN
.
The following table shows which selectors/combinators are supported along with the inferred return types for the given examples.
Selector/Combinator | Example | Compatibility | Inference | Before/After |
---|---|---|---|---|
Type + ID | div#app |
โ | Patched | Element /HTMLDivElement |
Type + Class | a.myLink |
โ | Patched | Element /HTMLAnchorElement |
Type + Attribute | a[title] |
โ | Patched | Element /HTMLAnchorElement |
Descendant | div video |
โ | Patched | Element /HTMLVideoElement |
Child | main > a |
โ | Patched | Element /HTMLAnchorElement |
Next-sibling | div + span |
โ | Patched | Element /HTMLSpanElement |
Subsequent-sibling | h1 ~ pre |
โ | Patched | Element /HTMLPreElement |
Pseudo-class :root | :root |
โ | Patched | Element /HTMLHtmlElement |
Column (1) | col || td |
โ | Patched | Element /HTMLTableCellElement |
Type | li |
โ | Native | HTMLLIElement /HTMLLIElement |
ID | #share |
โ | Native | Element /Element |
Class | .footer |
โ | Native | Element /Element |
Attribute | [title] |
โ | Native | Element /Element |
Universal | * |
โ | Native | Element /Element |
Unresolved | <any> |
โ | Native | Element /Element |
(1) The column combinator is a highly-experimental upcoming combinator "that is placed between two CSS selectors. It matches only those elements matched by the second selector that belong to the column elements matched by the first." (source: MDN )
main.js
const video = document.querySelector('div#app > video') // HTMLVideoElement | null
const audios = document.querySelectorAll('div#app > audio') // NodeListOf<HTMLAudioElement>
if(video) {
video.src = '<some_URL>' // now we can access all <video> properties and methods
}
if(audios.length > 0) {
audios[0].src = '<some_URL>' // ๐๐๐
}
๐ The changelog is available here, CHANGELOG.md.
Licensed under the MIT license which is available here, MIT license.
Consider buying me a coffee. โ

Thank you for supporting my efforts! ๐๐
๐ถ๏ธ Reads a JSON file into a Map. ๐ป
@igorskyflyer/extendable-string
๐ฆ ExtendableString allows you to create strings on steroids that have custom transformations applied to them, unlike common, plain strings.. ๐ช
๐ฅฝ Provides ways of parsing UNC paths and checking whether they are valid. ๐ฑ
โ DรบรถScrรญbรฎ allows you to convert letters with diacritics to regular letters. ๐ค
๐งฌ A lightweight JavaScript utility allowing deep copy-by-value of nested objects, arrays and arrays of objects. ๐ช
Created by Igor Dimitrijeviฤ (@igorskyflyer).