-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
misc: tighten querySelector types #12013
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,11 @@ | |
* Otherwise, minification will mangle the variable names and break usage. | ||
*/ | ||
|
||
/** @typedef {HTMLElementTagNameMap & {[id: string]: HTMLElement}} HTMLElementByTagName */ | ||
/** | ||
* `typed-query-selector`'s CSS selector parser. | ||
* @template {string} T | ||
* @typedef {import('typed-query-selector/parser').ParseSelector<T>} ParseSelector | ||
*/ | ||
|
||
/* global window document Node ShadowRoot HTMLElement */ | ||
|
||
|
@@ -98,19 +102,21 @@ function checkTimeSinceLastLongTask() { | |
* @template {string} T | ||
* @param {T} selector Optional simple CSS selector to filter nodes on. | ||
* Combinators are not supported. | ||
* @return {Array<HTMLElementByTagName[T]>} | ||
* @return {Array<ParseSelector<T>>} | ||
*/ | ||
function getElementsInDocument(selector) { | ||
const realMatchesFn = window.__ElementMatches || window.Element.prototype.matches; | ||
/** @type {Array<HTMLElement>} */ | ||
/** @type {Array<ParseSelector<T>>} */ | ||
const results = []; | ||
|
||
/** @param {NodeListOf<HTMLElement>} nodes */ | ||
/** @param {NodeListOf<Element>} nodes */ | ||
const _findAllElements = nodes => { | ||
for (let i = 0, el; el = nodes[i]; ++i) { | ||
if (!selector || realMatchesFn.call(el, selector)) { | ||
// @ts-expect-error - el is verified as matching above, tsc just can't verify it through the .call(). | ||
results.push(el); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought it would be real fancy to also type interface Element {
matches<S extends string>(selectors: S): this is ParseSelector<S>;
} and then As a result, there's no type guard and so |
||
|
||
// If the element has a shadow root, dig deeper. | ||
if (el.shadowRoot) { | ||
_findAllElements(el.shadowRoot.querySelectorAll('*')); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In personal projects I've started only ever adding
@ts-expect-error
to lines that areconst thing: Bar = foo
based on the number of times we've been screwed by ignoring the wrong errors :) I'm curious what your stance is on that.I don't think this case is particularly dangerous, it just made me think of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you're definitely right it's better, and maybe we should establish that as the pattern...the only error being suppressed would be the type change of
el
, while when it's on this line, it could also beresults
has the wrong type or whatever.My only hesitation is how annoying jsdoc is for this, turning two lines into three :) If only there was a
// @ts-expect-error-line
or something...worth it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(yes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, sure. I was mostly asking for future reviews if you're onboard with that policy too, but here is good :)