Cédric Bloem
Cédric Bloem

Reputation: 1555

Type 'Element' is missing the following properties from type 'SVGSVGElement'

So I have the following situation were TypeScript is driving me nuts.

Case: I receive a div with an SVG as a child element. I need to receive x, y, width and height attributes from that child SVG element.

 ...
 const ref = React.useRef<HTMLDivElement>(null)
  React.useEffect(() => {
    if (!viewBox) {
      if (ref.current !== null) {
        const svg: SVGElement = ref.current.children[0]

        // Get the basic x, y, width, height values from the svg element
        const x = svg.x.baseVal.value,
          y = svg.y.baseVal.value,
          width = svg.width.baseVal.value,
          height = svg.height.baseVal.value

        // Check if the svg already has a viewbox attribute
        let originalViewBox
        if (svg.attributes.length > 0) {
          Object.values(svg.attributes).forEach((value) => {
            if (value && value.name === 'viewBox') originalViewBox = value.value
          })
        }

        /*
          If there is a viewbox attribute, use those value's.
          Otherwise, we use the svg x, y, width and height attributes
        */
        setViewBox([originalViewBox ? originalViewBox : `${x}, ${y}, ${width}, ${height}`])
      }
    }
  }, [ref, viewBox])

  return (
    // Styled div element that wraps around the svg
    <Icon
      className={`${animated ? 'animated' : ''} ${className}`}
      color={color}
      inline={inline}
      onClick={onClick}
      ref={ref}
      stacked={stacked}
    >
      {/* The svg element. Ref does not work here because it returns current: null */}
      {SvgIcon && !viewBox ? <SvgIcon /> : <SvgIcon viewBox={viewBox} />}
    </Icon>
  )
}
...

However, even though I define my svg as an SVGElement, I get the following error from 'const svg'

Type 'Element' is missing the following properties from type 'SVGElement': ownerSVGElement, viewportElement, oncopy, oncut, and 90 more.

And this error from all the svg.x, svg.y. svg.width and svg.height parts:

Property 'width' (or x, y, height,..) does not exist on type 'SVGElement'.

When I change my first line to this:

const svg: SVGSVGElement = ref.current.children[0]

So, from SVGElement to SVGSVGElement, the only remaining error is the one on 'const svg', which now says:

Type 'Element' is missing the following properties from type 'SVGSVGElement': contentScriptType, contentStyleType, currentScale, currentTranslate, and 139 more.ts(2740)

What I'd like to know, is how I need to define my svg element to avoid errors (images below for more clearance)

enter image description here

Upvotes: 2

Views: 6038

Answers (1)

tmhao2005
tmhao2005

Reputation: 17484

Since .children method returns an HTMLCollection which each element is Element object which you can't assign to a different type like SVGSVGElement. But you can cast the type to make it work in your case:

const svg = ref.current?.children[0] as SVGSVGElement;

Upvotes: 4

Related Questions