SVGコンポーネントのプロパティの型を宣言するにはどうすればいいですか? [React、TypeScript、Webpack] 質問する

SVGコンポーネントのプロパティの型を宣言するにはどうすればいいですか? [React、TypeScript、Webpack] 質問する

基本的に、私がやりたいことは、SVG アイコンを React コンポーネントにインポートし、それにプロパティを追加することです。size="24px"コンポーネントとしてより柔軟にしたいです。または、classNameプロパティを追加して CSS で編集できるようにします (たとえば、hover プロパティを追加できます)。Webpack で TypeScript を使用するのは初めてなので、SVG 要素の型をどのように宣言すればよいのか混乱しており、エラーが発生します (以下を参照)。

SVG を組み込む方法はたくさんあるので、ReactComponent としてインポートすることにしました。

メニューアイコン.svg

<svg width="24" height="24" viewBox="0 0 24 24">
  <path fill="currentColor" fillRule="evenodd" d="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"></path>
</svg>

header.tsx (ここでは svg アイコンを使用します)

import React from 'react';
import MenuIcon from '../assets/menu-icon.svg';

const Header: React.SFC = () => {
  return (
    <header className="c-header u-side-paddings">
      <MenuIcon className="c-header__icon" />  // <-- className prop doesn't match provided type
    </header>
  );
};

export default Header;

index.d.ts (.svg ファイルをコンポーネントとして扱うことができる)

declare module '*.svg' {
  import React = require('react');
  export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

MenuIcon SVG コンポーネントに prop を追加するとclassNameエラーが発生します。

(JSX attribute) className: string
Type '{ className: string; }' is not assignable to type 'IntrinsicAttributes'.
  Property 'className' does not exist on type 'IntrinsicAttributes'.ts(2322)

これまでの私の理解

  • div内にsvgコンポーネントをラップして、className次のように追加することもできます<div className="c-header__icon"><MenuIcon/></div>が、これはエレガントではない解決策であり、あまり良い方法ではないと思います。
  • 私は学んだこの答えSVG プロパティはオブジェクトなので文字列ではありませんSVGAnimatedString。つまり:
  • index.d.ts.svg の代わりに .tsx ファイルを作成しようとしましたが (その場合は ファイルは必要ありません)、classNameのタイプがの場合にのみ機能しますstring。また、 とは異なる拡張子のファイルに SVG アイコンを保存するのが良い方法かどうかはわかりません.svg。私の意見では、それは明確さのために良くありません。私が間違っている場合は、実際に良い方法を教えてください。例を示します。
    import React from 'react';
    
    interface MenuIcon {
      className?: SVGAnimatedString;
    }
    
    export class MenuIcon extends React.PureComponent<MenuIcon> {
      render() {
        return (
          <svg width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" fillRule="evenodd" d="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"></path>
    </svg>
        );
      }
    }

基礎が足りないような気がします。いくつかのトピックが組み合わさっているので、何に焦点を当てるべきか判断するのが本当に難しいです。

ベストアンサー1

私はこの問題に直面していましたが、この解決策はうまくいきました:

declare module "*.svg" {
   import { FC, SVGProps } from "react";
   const content: FC<SVGProps<SVGElement>>;
   export default content;
}

それに、私は@svgr/ウェブパックNext.jsとともにSVGローダーとして

おすすめ記事