defineProperties(Element.prototype, {
querySelector: {
value: querySelectorPatched,
writable: true,
enumerable: true,
configurable: true,
},
querySelectorAll: {
value(this: HTMLBodyElement): NodeListOf<Element> {
const nodeList = arrayFromCollection(
elementQuerySelectorAll.apply(this, ArraySlice.call(arguments) as [string])
);
if (!featureFlags.ENABLE_NODE_LIST_PATCH) {
const filteredResults = getFilteredArrayOfNodes(
this,
nodeList,
ShadowDomSemantic.Disabled
);
return createStaticNodeList(filteredResults);
}
return createStaticNodeList(
getFilteredArrayOfNodes(this, nodeList, ShadowDomSemantic.Enabled)
);
},
writable: true,
enumerable: true,
configurable: true,
},
});
I want to understand this part of the following Typescript code here:
value(this: HTMLBodyElement): NodeListOf<Element>
I believe this code is overriding the standard querySelectorAll
method. But the method is being defined on an Element
, yet the value for this
in the function is HTMLBodyElement
. Does this mean the method can only be called from a body
element? Or perhaps it's called from Element
and then casted to HTMLBodyElement
? Can someone explain the logic of this code? This is a part of the following repository.
What does ?: mean in TypeScript? Using a question mark followed by a colon ( ?: ) means a property is optional. That said, a property can either have a value based on the type defined or its value can be undefined .
Similar to JavaScript, to pass a function as a parameter in TypeScript, define a function expecting a parameter that will receive the callback function, then trigger the callback function inside the parent function.
Introduction to TypeScript void type The void type denotes the absence of having any type at all. It is a little like the opposite of the any type. Typically, you use the void type as the return type of functions that do not return a value.
Use the ReturnType utility type to get the return type of a function in TypeScript, e.g. type T = ReturnType<typeof myFunction> . The ReturnType utility type constructs a type that consists of the return type of the provided function type.
Nobody will explain this better than the developers of that project, but it totally looks like a mistake to me.
this
is only being used in three function calls of two different types, in which it is passed as one parameter:
function querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
function getFilteredArrayOfNodes<T extends Node>(
context: Element,
unfilteredNodes: T[],
shadowDomSemantic: ShadowDomSemantic
): T[]
When passing this
typed as HTMLBodyElement
to each of these functions, the type is actually always widened as Element
, even in querySelectorAll
because there is no type provided between angle brackets and no possible inference so the resolved E
type is Element
(the default type).
According to me, value(this: HTMLBodyElement)
should be value(this: Element)
because it is meant to override Element.prototype.querySelectorAll
.
Doing so doesn't break anything in the code and is much more correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With