title: How to declare types of props of SVG component? [React, TypeScript and Webpack]
body: <p>Basically, what I want to do is to import an SVG icon to my react component and add props to it. Like <code>size=&quot;24px&quot;</code> to make it more flexible as a component. Or make it editable with CSS by adding <code>className</code> prop (so I could add e.g. hover prop to it).
  As it's my first time using TypeScript with Webpack, I'm being confused about how should I declare types for SVG element and I get an error (shown below)</p>
  <p>As there are many ways of include SVG I decided to import it as a ReactComponent.</p>
  <p>menu-icon.svg</p>
  <pre><code>&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;
    &lt;path fill=&quot;currentColor&quot; fillRule=&quot;evenodd&quot; d=&quot;M4.5 5h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;
  </code></pre>
  <p>header.tsx (here I want my svg icon)</p>
  <pre><code>import React from 'react';
  import MenuIcon from '../assets/menu-icon.svg';
  
  const Header: React.SFC = () =&gt; {
    return (
      &lt;header className=&quot;c-header u-side-paddings&quot;&gt;
        &lt;MenuIcon className=&quot;c-header__icon&quot; /&gt;  // &lt;-- className prop doesn't match provided type
      &lt;/header&gt;
    );
  };
  
  export default Header;
  </code></pre>
  <p>index.d.ts (so the .svg file can be treated as a component)</p>
  <pre><code>declare module '*.svg' {
    import React = require('react');
    export const ReactComponent: React.SFC&lt;React.SVGProps&lt;SVGSVGElement&gt;&gt;;
    const src: string;
    export default src;
  }
  </code></pre>
  <p>Adding <code>className</code> prop to MenuIcon SVG Component causes an error:</p>
  <pre><code>(JSX attribute) className: string
  Type '{ className: string; }' is not assignable to type 'IntrinsicAttributes'.
    Property 'className' does not exist on type 'IntrinsicAttributes'.ts(2322)
  </code></pre>
  <h3>My understanding so far</h3>
  <ul>
  <li>I could just wrap svg component inside a div, and add a <code>className</code> to it like that: <code>&lt;div className=&quot;c-header__icon&quot;&gt;&lt;MenuIcon/&gt;&lt;/div&gt;</code> but I feel like it's an inelegant solution and not really a good practice</li>
  <li>I learned from <a href="https://stackoverflow.com/a/37949156/9212198">this answer</a> that SVG props aren't strings, cuz they're an <code>SVGAnimatedString</code> objects. So:</li>
  <li>I tried to create .tsx file instead of .svg (I wouldn't need <code>index.d.ts</code> file then), but it works only if <code>className</code>'s type is <code>string</code>. Also I'm not sure if it's a good practice to store SVG icons in files with different extension that <code>.svg</code>. In my opinion it's not good for clarity. If I'm wrong, tell me what actually good practices are, please. Here's the example:</li>
  </ul>
  <pre><code>    import React from 'react';
      
      interface MenuIcon {
        className?: SVGAnimatedString;
      }
      
      export class MenuIcon extends React.PureComponent&lt;MenuIcon&gt; {
        render() {
          return (
            &lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;
        &lt;path fill=&quot;currentColor&quot; fillRule=&quot;evenodd&quot; d=&quot;M4.5 5h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm0 
   6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1z&quot;&gt;&lt;/path&gt;
      &lt;/svg&gt;
          );
        }
      }
  </code></pre>
  <p>I feel like I'm in lack of some basics, It's just really hard for me to figure out what should I focus on, as there are several topics combined</p>