An open API service indexing awesome lists of open source software.

https://github.com/igorskyflyer/npm-magic-queryselector

๐Ÿช„ A TypeScript-types patch for querySelector/querySelectorAll, make them return types you expect them to! ๐Ÿ”ฎ
https://github.com/igorskyflyer/npm-magic-queryselector

back-end biome combinator css dom dom-manipulation html igorskyflyer javascript js magic node query queryselector queryselectorall selector ts typescript

Last synced: 6 months ago
JSON representation

๐Ÿช„ A TypeScript-types patch for querySelector/querySelectorAll, make them return types you expect them to! ๐Ÿ”ฎ

Awesome Lists containing this project

README

          


Icon of Magic querySelector

Magic querySelector




๐Ÿช„ A TypeScript-types patch for querySelector() / querySelectorAll(), make them return types you expect them to! ๐Ÿ”ฎ




## ๐Ÿ“ƒ Table of Contents

- [Features](#-features)
- [Usage](#-usage)
- [TypeScript](#typescript)
- [Create a d.ts file](#create-a-dts-file-recommended)
- [Add to the entrypoint](#add-to-the-entrypoint)
- [JavaScript](#javascript)
- [API](#-api)
- [Implementation table](#implementation-table)
- [Examples](#๏ธ-examples)
- [Changelog](#-changelog)
- [Support](#-support)
- [License](#-license)
- [Related](#-related)
- [Author](#-author)




## ๐Ÿค– Features

- ๐Ÿง  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`, and `attribute` selectors in type space
- ๐Ÿ”— Combinator awareness - understands `descendant`, `child`, `sibling`, and `column combinators`
- ๐ŸŒฑ Pseudoโ€‘class support - recognizes `:root` and maps it to the `` element type
- ๐Ÿ“œ Global augmentation - extends `Document` and `Element` to return precise types for `querySelector`/`querySelectorAll`
- โšก Zero runtime cost - all logic is purely in TypeScript types, no JS overhead




## ๐Ÿ•ต๐Ÿผ Usage

Install it by executing any of the following, depending on your preferred package manager:

```bash
pnpm add @igorskyflyer/magic-queryselector
```

```bash
yarn add @igorskyflyer/magic-queryselector
```

```bash
npm i @igorskyflyer/magic-queryselector
```




Here's `magic-querySelector` in action.


https://github.com/user-attachments/assets/eb0b6695-be60-4a6e-b935-5996b40c5d78


Without magic-queryselector




https://github.com/user-attachments/assets/2251724d-98d7-4deb-8a82-8b4f0a6a6e31


With magic-queryselector




Visual Studio Code theme used in the demonstration is Kai ๐ŸŒŠ An external link.


Including the `magic-queryselector` into your project depends on the language of it. Please see the appropriate section for your project:

- [TypeScript](#typescript)
- [JavaScript](#javascript)

---

### TypeScript

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:

```ts
import '@igorskyflyer/magic-queryselector'
```

and then do one of the either options:


**\[ 1st option ]**
#### Create a `d.ts` file (*recommended*)


> ### โš ๏ธ WARNING
>
> 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`
```ts
import '@igorskyflyer/magic-queryselector'
```


That's it! You're all set up. ๐Ÿฅณ


> ### ๐Ÿ’ก TIP
>
> #### Language server
>
> 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 to the entrypoint

Add the code snippet you copied to the top of your entrypoint/main TypeScript file.


`index.ts`
```ts
import '@igorskyflyer/magic-queryselector'
```


> ### ๐Ÿ’ก TIP
>
> #### Language server
>
> 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.
>

---

### JavaScript


> ### โ„น๏ธ NOTE
>
> #### Easy install
>
> If you want to use it with JavaScript, you don't need to do anything besides installing the package.
>


> ### ๐Ÿ’ก TIP
>
> #### Language server
>
> 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.
>




## ๐Ÿคน๐Ÿผ API

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()`.


> ### โ„น๏ธ NOTE
>
> #### API behavior
>
> `querySelector()` will return the type listed in the table below, e.g. `HTMLDivElement`, while `querySelectorAll()` will return `NodeListOf` of the same type, e.g. `NodeListOf`.
>
> **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](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors/Selector_structure) ![External link](https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/external.svg) and [selectors and combinators](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors/Selectors_and_combinators) ![External link](https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/external.svg) on `MDN`.
>


The following table shows which selectors/combinators are supported along with the inferred return types for the given examples.


##### Implementation table
|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 |`` | โ€” | *Native* |`Element`/`Element` |

Table 1. implementation table




***(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](https://developer.mozilla.org/en-US/docs/Web/CSS/Column_combinator) An external link)




## ๐Ÿ—’๏ธ Examples

`main.js`
```js
const video = document.querySelector('div#app > video') // HTMLVideoElement | null
const audios = document.querySelectorAll('div#app > audio') // NodeListOf

if(video) {
video.src = '' // now we can access all properties and methods
}

if(audios.length > 0) {
audios[0].src = '' // ๐Ÿ˜€๐Ÿ˜€๐Ÿ˜€
}
```




## ๐Ÿ“ Changelog

๐Ÿ“‘ The changelog is available here, [CHANGELOG.md](https://github.com/igorskyflyer/npm-magic-queryselector/blob/main/CHANGELOG.md).




## ๐Ÿชช License

Licensed under the MIT license which is available here, [MIT license](https://github.com/igorskyflyer/npm-magic-queryselector/blob/main/LICENSE).




## ๐Ÿ’– Support


I work hard for every project, including this one and your support means a lot to me!


Consider buying me a coffee. โ˜•




Donate to igorskyflyer




Thank you for supporting my efforts! ๐Ÿ™๐Ÿ˜Š




## ๐Ÿงฌ Related

[@igorskyflyer/jmap](https://www.npmjs.com/package/@igorskyflyer/jmap)

> _๐Ÿ•ถ๏ธ Reads a JSON file into a Map. ๐ŸŒป_


[@igorskyflyer/extendable-string](https://www.npmjs.com/package/@igorskyflyer/extendable-string)

> _๐Ÿฆ€ ExtendableString allows you to create strings on steroids that have custom transformations applied to them, unlike common, plain strings.. ๐Ÿช€_


[@igorskyflyer/unc-path](https://www.npmjs.com/package/@igorskyflyer/unc-path)

> _๐Ÿฅฝ Provides ways of parsing UNC paths and checking whether they are valid. ๐ŸŽฑ_


[@igorskyflyer/duoscribi](https://www.npmjs.com/package/@igorskyflyer/duoscribi)

> _โœ’ DรบรถScrรญbรฎ allows you to convert letters with diacritics to regular letters. ๐Ÿค“_


[@igorskyflyer/clone](https://www.npmjs.com/package/@igorskyflyer/clone)

> _๐Ÿงฌ A lightweight JavaScript utility allowing deep copy-by-value of nested objects, arrays and arrays of objects. ๐Ÿช_






## ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป Author
Created by **Igor Dimitrijeviฤ‡** ([*@igorskyflyer*](https://github.com/igorskyflyer/)).