Reputation: 1555
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)
Upvotes: 2
Views: 6038
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