{"id":18396721,"url":"https://github.com/igorskyflyer/npm-magic-queryselector","last_synced_at":"2026-01-07T01:04:17.986Z","repository":{"id":248741116,"uuid":"829570542","full_name":"igorskyflyer/npm-magic-queryselector","owner":"igorskyflyer","description":"🪄 A TypeScript-types patch for querySelector/querySelectorAll, make them return types you expect them to! 🔮","archived":false,"fork":false,"pushed_at":"2024-07-28T21:39:29.000Z","size":8834,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-08T00:04:46.081Z","etag":null,"topics":["back-end","biome","combinator","css","dom","dom-manipulation","html","igorskyflyer","javascript","js","magic","node","query","queryselector","queryselectorall","selector","ts","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@igor.dvlpr/magic-queryselector","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/igorskyflyer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"igorskyflyer"}},"created_at":"2024-07-16T17:44:26.000Z","updated_at":"2024-07-28T21:39:32.000Z","dependencies_parsed_at":"2024-07-20T17:58:28.286Z","dependency_job_id":null,"html_url":"https://github.com/igorskyflyer/npm-magic-queryselector","commit_stats":null,"previous_names":["igorskyflyer/npm-magic-queryselector"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-magic-queryselector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-magic-queryselector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-magic-queryselector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-magic-queryselector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igorskyflyer","download_url":"https://codeload.github.com/igorskyflyer/npm-magic-queryselector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245756354,"owners_count":20667144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["back-end","biome","combinator","css","dom","dom-manipulation","html","igorskyflyer","javascript","js","magic","node","query","queryselector","queryselectorall","selector","ts","typescript"],"created_at":"2024-11-06T02:14:39.194Z","updated_at":"2026-01-07T01:04:17.980Z","avatar_url":"https://github.com/igorskyflyer.png","language":null,"funding_links":["https://ko-fi.com/igorskyflyer"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/npm-magic-queryselector/main/media/magic-queryselector.png\" alt=\"Icon of Magic querySelector\" width=\"256\" height=\"256\"\u003e\n  \u003ch1\u003eMagic querySelector\u003c/h1\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n\u003ch4 align=\"center\"\u003e\n  🪄 A TypeScript-types patch for \u003ccode\u003equerySelector()\u003c/code\u003e / \u003ccode\u003equerySelectorAll()\u003c/code\u003e, make them return types you expect them to! 🔮\n\u003c/h4\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 📃 Table of Contents\n\n- [Features](#-features)\n- [Usage](#-usage)\n  - [TypeScript](#typescript)\n    - [Create a d.ts file](#create-a-dts-file-recommended)\n    - [Add to the entrypoint](#add-to-the-entrypoint)\n  - [JavaScript](#javascript)\n- [API](#-api)\n  - [Implementation table](#implementation-table)\n- [Examples](#️-examples)\n- [Changelog](#-changelog)\n- [Support](#-support)\n- [License](#-license)\n- [Related](#-related)\n- [Author](#-author)\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🤖 Features\n\n- 🧠 Smart IntelliSense - auto‑suggests valid `CSS selectors` and infers exact element types\n- 📌 Works with literal selector strings to power IntelliSense\n- 🪄 Type‑driven safety - catches invalid selectors at compile time in TypeScript\n- 🏷 Tag name mapping - resolves HTML tag names to their correct HTMLElement types\n- 🎯 Selector parsing - supports `tag`, `class`, `ID`, and `attribute` selectors in type space\n- 🔗 Combinator awareness - understands `descendant`, `child`, `sibling`, and `column combinators`\n- 🌱 Pseudo‑class support - recognizes `:root` and maps it to the `\u003chtml\u003e` element type\n- 📜 Global augmentation - extends `Document` and `Element` to return precise types for `querySelector`/`querySelectorAll`\n- ⚡ Zero runtime cost - all logic is purely in TypeScript types, no JS overhead\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🕵🏼 Usage\n\nInstall it by executing any of the following, depending on your preferred package manager:\n\n```bash\npnpm add @igorskyflyer/magic-queryselector\n```\n\n```bash\nyarn add @igorskyflyer/magic-queryselector\n```\n\n```bash\nnpm i @igorskyflyer/magic-queryselector\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\nHere's `magic-querySelector` in action.\n\n\u003cbr\u003e\n\nhttps://github.com/user-attachments/assets/eb0b6695-be60-4a6e-b935-5996b40c5d78\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eWithout\u003c/strong\u003e \u003ccode\u003emagic-queryselector\u003c/code\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\nhttps://github.com/user-attachments/assets/2251724d-98d7-4deb-8a82-8b4f0a6a6e31\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eWith\u003c/strong\u003e \u003ccode\u003emagic-queryselector\u003c/code\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\u003cblockquote align=\"center\"\u003eVisual Studio Code theme used in the demonstration is \u003ca href=\"https://marketplace.visualstudio.com/items?itemName=igordvlpr.kai-theme\"\u003e\u003ccode\u003eKai 🌊\u003c/code\u003e\u003c/a\u003e \u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/external.svg\" alt=\"An external link\" width=\"12\" height=\"12\"\u003e.\u003c/blockquote\u003e\n\n\u003cbr\u003e\n\nIncluding the `magic-queryselector` into your project depends on the language of it. Please see the appropriate section for your project:\n\n- [TypeScript](#typescript)\n- [JavaScript](#javascript)\n\n---\n\n### TypeScript\n\nIf 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.\n\nTo do so, copy the following code:\n\n```ts\nimport '@igorskyflyer/magic-queryselector'\n```\n\nand then do one of the either options:\n\n\u003cbr\u003e\n\n**\\[ 1st option ]**\n#### Create a `d.ts` file (*recommended*)\n\n\u003cbr\u003e\n\n\u003e ### ⚠️ WARNING\n\u003e\n\u003e This method requires a valid `tsconfig.json` file to be present in the root of your project.\n\u003e\n\n\u003cbr\u003e\n\nCreate a `magic.d.ts` file in the root directory of your project and add the snippet you copied:\n\n\u003cbr\u003e\n\n`magic.d.ts`\n```ts\nimport '@igorskyflyer/magic-queryselector'\n```\n\n\u003cbr\u003e\n\nThat's it! You're all set up. 🥳\n\n\u003cbr\u003e\n\n\u003e ### 💡 TIP\n\u003e\n\u003e #### Language server\n\u003e\n\u003e 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.\n\u003e\n\n---\n\n\u003cbr\u003e\n\n**\\[ 2nd option ]**\n#### Add to the entrypoint\n\n\nAdd the code snippet you copied to the top of your entrypoint/main TypeScript file.\n\n\u003cbr\u003e\n\n`index.ts`\n```ts\nimport '@igorskyflyer/magic-queryselector'\n```\n\n\u003cbr\u003e\n\n\u003e ### 💡 TIP\n\u003e\n\u003e #### Language server\n\u003e\n\u003e 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.\n\u003e\n\n---\n\n### JavaScript\n\n\n\u003cbr\u003e\n\n\u003e ### ℹ️ NOTE\n\u003e\n\u003e #### Easy install\n\u003e\n\u003e If you want to use it with JavaScript, you don't need to do anything besides installing the package.\n\u003e\n\n\u003cbr\u003e\n\n\u003e ### 💡 TIP\n\u003e\n\u003e #### Language server\n\u003e\n\u003e 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.\n\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🤹🏼 API\n\nThis patch extends the default (*return*) type inference of TypeScript by inferring the types from the input `string` containing selectors/combinators passed to `querySelector()` / `querySelectorAll()`.\n\n\u003cbr\u003e\n\n\u003e ### ℹ️ NOTE\n\u003e\n\u003e #### API behavior\n\u003e\n\u003e `querySelector()` will return the type listed in the table below, e.g. `HTMLDivElement`, while `querySelectorAll()` will return `NodeListOf\u003cT\u003e` of the same type, e.g. `NodeListOf\u003cHTMLDivElement\u003e`.\n\u003e\n\u003e **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.\n\u003e\n\u003e For brevity this table only shows the types for `querySelector()`.\n\u003e\n\u003e 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`.\n\u003e\n\n\u003cbr\u003e\n\nThe following table shows which selectors/combinators are supported along with the inferred return types for the given examples.\n\n\u003cbr\u003e\n\n##### Implementation table\n|Selector/Combinator |Example      |Compatibility | Inference   |Before/After                    |\n|:------------------:|:-----------:|:------------:|:-----------:|:------------------------------:|\n|Type + ID           |`div#app`    | ✅           | **Patched** |`Element`/`HTMLDivElement`      |\n|Type + Class        |`a.myLink`   | ✅           | **Patched** |`Element`/`HTMLAnchorElement`   |\n|Type + Attribute    |`a[title]`   | ✅           | **Patched** |`Element`/`HTMLAnchorElement`   |\n|Descendant          |`div video`  | ✅           | **Patched** |`Element`/`HTMLVideoElement`    |\n|Child               |`main \u003e a`   | ✅           | **Patched** |`Element`/`HTMLAnchorElement`   |\n|Next-sibling        |`div + span` | ✅           | **Patched** |`Element`/`HTMLSpanElement`     |\n|Subsequent-sibling  |`h1 ~ pre`   | ✅           | **Patched** |`Element`/`HTMLPreElement`      |\n|Pseudo-class :root  |`:root`      | ✅           | **Patched** |`Element`/`HTMLHtmlElement`     |\n|Column (1)          |`col \\|\\| td`| ✅           | **Patched** |`Element`/`HTMLTableCellElement`|\n|Type                |`li`         | \u0026mdash;      | *Native*    |`HTMLLIElement`/`HTMLLIElement` |\n|ID                  |`#share`     | \u0026mdash;      | *Native*    |`Element`/`Element`             |\n|Class               |`.footer`    | \u0026mdash;      | *Native*    |`Element`/`Element`             |\n|Attribute           |`[title]`    | \u0026mdash;      | *Native*    |`Element`/`Element`             |\n|Universal           |`*`          | \u0026mdash;      | *Native*    |`Element`/`Element`             |\n|Unresolved          |`\u003cany\u003e`      | \u0026mdash;      | *Native*    |`Element`/`Element`             |\n\n\u003cdiv align=\"center\"\u003e\u003cem\u003e\u003cstrong\u003eTable 1.\u003c/strong\u003e implementation table\u003c/em\u003e\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n***(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) \u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/external.svg\" alt=\"An external link\" width=\"12\" height=\"12\"\u003e)\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🗒️ Examples\n\n`main.js`\n```js\nconst video = document.querySelector('div#app \u003e video') // HTMLVideoElement | null\nconst audios = document.querySelectorAll('div#app \u003e audio') // NodeListOf\u003cHTMLAudioElement\u003e\n\nif(video) {\n  video.src = '\u003csome_URL\u003e' // now we can access all \u003cvideo\u003e properties and methods\n}\n\nif(audios.length \u003e 0) {\n  audios[0].src = '\u003csome_URL\u003e' // 😀😀😀\n}\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 📝 Changelog\n\n📑 The changelog is available here, [CHANGELOG.md](https://github.com/igorskyflyer/npm-magic-queryselector/blob/main/CHANGELOG.md).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🪪 License\n\nLicensed under the MIT license which is available here, [MIT license](https://github.com/igorskyflyer/npm-magic-queryselector/blob/main/LICENSE).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 💖 Support\n\n\u003cdiv align=\"center\"\u003e\n  I work hard for every project, including this one and your support means a lot to me!\n  \u003cbr\u003e\n  Consider buying me a coffee. ☕\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://ko-fi.com/igorskyflyer\" target=\"_blank\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/ko-fi.png\" alt=\"Donate to igorskyflyer\" width=\"180\" height=\"46\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cem\u003eThank you for supporting my efforts!\u003c/em\u003e 🙏😊\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🧬 Related\n\n[@igorskyflyer/jmap](https://www.npmjs.com/package/@igorskyflyer/jmap)\n\n\u003e _🕶️ Reads a JSON file into a Map. 🌻_\n\n\u003cbr\u003e\n\n[@igorskyflyer/extendable-string](https://www.npmjs.com/package/@igorskyflyer/extendable-string)\n\n\u003e _🦀 ExtendableString allows you to create strings on steroids that have custom transformations applied to them, unlike common, plain strings.. 🪀_\n\n\u003cbr\u003e\n\n[@igorskyflyer/unc-path](https://www.npmjs.com/package/@igorskyflyer/unc-path)\n\n\u003e _🥽 Provides ways of parsing UNC paths and checking whether they are valid. 🎱_\n\n\u003cbr\u003e\n\n[@igorskyflyer/duoscribi](https://www.npmjs.com/package/@igorskyflyer/duoscribi)\n\n\u003e _✒ DúöScríbî allows you to convert letters with diacritics to regular letters. 🤓_\n\n\u003cbr\u003e\n\n[@igorskyflyer/clone](https://www.npmjs.com/package/@igorskyflyer/clone)\n\n\u003e _🧬 A lightweight JavaScript utility allowing deep copy-by-value of nested objects, arrays and arrays of objects. 🪁_\n\n\u003cbr\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 👨🏻‍💻 Author\nCreated by **Igor Dimitrijević** ([*@igorskyflyer*](https://github.com/igorskyflyer/)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorskyflyer%2Fnpm-magic-queryselector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figorskyflyer%2Fnpm-magic-queryselector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorskyflyer%2Fnpm-magic-queryselector/lists"}