domutils icon indicating copy to clipboard operation
domutils copied to clipboard

problems with typescript

Open 0x0a0d opened this issue 4 years ago • 2 comments

I got multiple problems when using DomUtils with typescript

DomUtils.findAll(el => el.name === 'div' && el.parent?.name === 'body', dom.children')

TS2339: Property 'name' does not exist on type 'NodeWithChildren'.


DomUtils.getElements({name: 'div'}, dom.children).map(elment => element.children)

TS2339: Property 'children' does not exist on type 'Node'.


find(test: (elem: Node) => boolean, nodes: Node[], recurse: boolean, limit: number): Node[]
findAll(test: (elem: Element) => boolean, nodes: Node[]): Element[]

Why typeof test's params of find is Node but findAll is Element? and their return too?


There are cases like these but I can't remember now

How to be clear

Why getElements not return Element[] ?

When will method return Element, Node, NodeWithChildren, ... ?

Thanks

0x0a0d avatar Sep 28 '21 20:09 0x0a0d

Hi @0x0a0d, thanks for opening this, and sorry for never responding. I agree that the current DOM structure isn't ideal, and I am thinking about how to improve it. You point at real issues with the current types, and I'd like to keep the issue open — hope that's okay!

fb55 avatar Apr 02 '22 16:04 fb55

Okay, let's address this:

  1. The issue here is el.parent?.name === 'body', as the parent isn't guaranteed to be a tag (it could also be the document). You can work around this with an additional check: el.parent?.type === 'tag' && el.parent.name === 'body'.
  2. getElements is inherited from the original node-htmlparser project and provides filters for any kind of node. For a simple name filter, you can use getElementsByTagName; this will only return elements.
  3. find similarly allows you to get any kind of node, while findAll is limited to elements. Agreed that this is confusing. I have added a documentation comment for now.

fb55 avatar Apr 22 '22 08:04 fb55

I found the correct way to do it

DomUtils.find(el=> el instanceof Element /* && any conditions */, children, false, 10) as Element[]

0x0a0d avatar Nov 07 '22 23:11 0x0a0d

I think most of this has been resolved, even though there are still plenty of casts and type checks that are necessary.

fb55 avatar Apr 29 '23 09:04 fb55