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, }, });Quiero entender esta parte del siguiente código mecanografiado aquí:
value(this: HTMLBodyElement): NodeListOf<Element> Creo que este código anula el método estándar querySelectorAll . Pero el método se define en un Element , pero el valor de this en la función es HTMLBodyElement . ¿Significa esto que el método solo se puede llamar desde un elemento del body ? ¿O tal vez se llama desde Element y luego se envía a HTMLBodyElement ? ¿Alguien puede explicar la lógica de este código? Esto es parte del siguiente repositorio .
Nadie explicará esto mejor que los desarrolladores de ese proyecto, pero me parece totalmente un error.
this solo se usa en tres llamadas de función de dos tipos diferentes, en las que se pasa como un parámetro:
function querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>; function getFilteredArrayOfNodes<T extends Node>( context: Element, unfilteredNodes: T[], shadowDomSemantic: ShadowDomSemantic ): T[] Al pasar this escrito como HTMLBodyElement a cada una de estas funciones, el tipo en realidad siempre se amplía como Element , incluso en querySelectorAll porque no se proporciona ningún tipo entre paréntesis angulares y no hay inferencia posible, por lo que el tipo E resuelto es Element (el tipo predeterminado).
Según yo, value(this: HTMLBodyElement) debería ser value(this: Element) porque está destinado a anular Element.prototype.querySelectorAll .
Hacerlo no rompe nada en el código y es mucho más correcto.