Flow version: trunk
SVG elements are actually of type HTMLElement.
document.createElement('svg') instanceof HTMLElement &&
document.createElement('animate') instanceof HTMLElement &&
document.createElement('circle') instanceof HTMLElement &&
document.createElement('defs') instanceof HTMLElement &&
document.createElement('ellipse') instanceof HTMLElement &&
document.createElement('g') instanceof HTMLElement &&
document.createElement('image') instanceof HTMLElement &&
document.createElement('line') instanceof HTMLElement &&
document.createElement('linearGradient') instanceof HTMLElement &&
document.createElement('mask') instanceof HTMLElement &&
document.createElement('path') instanceof HTMLElement &&
document.createElement('pattern') instanceof HTMLElement &&
document.createElement('polygon') instanceof HTMLElement &&
document.createElement('polyline') instanceof HTMLElement &&
document.createElement('radialGradient') instanceof HTMLElement &&
document.createElement('rect') instanceof HTMLElement &&
document.createElement('stop') instanceof HTMLElement &&
document.createElement('symbol') instanceof HTMLElement &&
document.createElement('text') instanceof HTMLElement &&
document.createElement('tspan') instanceof HTMLElement &&
document.createElement('use') instanceof HTMLElement
> true
Currently they are typed as Element which is too restrictive (eg. when trying to use React refs with SVG elements)
SVG is distinctly not part of the HTML spec. It has its own spec. Here is the PR you should be looking at: https://github.com/facebook/flow/pull/4551
Interesting. Would #4551 address the fact that this is a Flow error right now?
const ref = React.useRef<HTMLElement | null>(null);
return <svg ref={ref} />;
No, because an SVGElement extends Element. The SVG spec even defines the SVGElement interface by extending from Element:
[Exposed=Window]
interface SVGElement : Element {
[SameObject] readonly attribute SVGAnimatedString className;
readonly attribute SVGSVGElement? ownerSVGElement;
readonly attribute SVGElement? viewportElement;
};
SVGElement includes GlobalEventHandlers;
SVGElement includes DocumentAndElementEventHandlers;
SVGElement includes SVGElementInstance;
SVGElement includes HTMLOrSVGElement;
The "correct" way to create SVG elements via the DOM interface is like so:
document.createElementNS("http://www.w3.org/2000/svg", "svg") instanceof HTMLElement
// false
document.createElementNS("http://www.w3.org/2000/svg", "svg") instanceof SVGElement
// true
The way to address your flow error right now would be to do:
const ref = React.useRef<Element | null>(null);
return <svg xmlns="http://www.w3.org/2000/svg" ref={ref} />;
When/if the aforementioned PR gets merged the solution would be to do:
const ref = React.useRef<SVGElement | null>(null);
return <svg xmlns="http://www.w3.org/2000/svg" ref={ref} />;
When/if the aforementioned PR gets merged
Aug 6, 2017
馃槅 馃槩
Most helpful comment
No, because an
SVGElementextendsElement. The SVG spec even defines theSVGElementinterface by extending fromElement:The "correct" way to create SVG elements via the DOM interface is like so:
The way to address your flow error right now would be to do:
When/if the aforementioned PR gets merged the solution would be to do: