44

I'm trying to import an .svg file as a React component with TypeScript.

According to the React docs, this is done like so:

import { ReactComponent as Icon } from './Icon.svg';

Following the TypeScript docs, I've added this:

// custom.d.ts

declare module '*.svg' {
    const content: any;
    export default content;
}

and

// tsconfig.json

{
    ...
    "files": [
        "custom.d.ts"
    ]
}

The SVG is rendering. But I'm getting a TypeScript error:

[ts] Module '"*.svg"' has no exported member 'ReactComponent'. [2305]

Here is my full tsconfig file if that helps:

{
  "compileOnSave": false,
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "jsx": "react",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "removeComments": false,
    "preserveConstEnums": true,
    "sourceMap": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "baseUrl": ".",
    "plugins": [
      {
        "name": "typescript-styled-plugin"
      }
    ],
    "typeRoots": ["./node_modules/@types"],
    "lib": ["dom", "es2015", "es2017"]
  },
  "exclude": ["node_modules", "dist"],
  "files": [
    "custom.d.ts"
  ]
}

Thank you!

Scott Baker
  • 10,013
  • 17
  • 56
  • 102
Matt Thomas
  • 865
  • 1
  • 13
  • 27

7 Answers7

106

You have export default content; But you are doing a named import (not a default import).

Fix

Change declaration to export the name you are importing:

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

Additional

Recommend not using files in tsconfig.json. Instead just use include

basarat
  • 261,912
  • 58
  • 460
  • 511
19

2019 In addition to @basarat's answer: React.SFC is depracated now consider using React.FunctionComponent like:

declare module '*.svg' {
    import React = require('react');
    export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
    const src: string;
    export default src;
}
MarcoLe
  • 2,309
  • 6
  • 36
  • 74
8

You're naming the custom types as custom.ts.d and it should call custom.d.ts once the ts compiler is configured to process ts|tsx extensions.

After that, you should be able to reference it into your tsconfig.json include section just like this:

"include": ["custom.d.ts"]
Caio Lucas
  • 139
  • 1
  • 4
6

If you already have plugin vite-plugin-svgr installed, simply add this following line to your vite-env.d.ts file:

/// <reference types="vite-plugin-svgr/client" />
Quan Nguyen
  • 59
  • 1
  • 4
2

Install svgr plugin and add this to tsconfig files: types": ["vite-plugin-svgr/client"]

axrmr
  • 21
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 16 '23 at 09:03
  • This worked for me – Hans Jul 18 '23 at 16:54
0

Pull request link

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

Just because it was helpful to me and somewhat related. If you're getting an error with Jest, check this out

Matt Thomas
  • 865
  • 1
  • 13
  • 27
0

My friends, if you are using Vite and vite-plugin-svgr, just follow these steps:

  1. Create a declaration file, name: client.d.ts (doesn't matter in types folder or in the root)

  2. Add this line of code to that file:

    /// <reference types="vite-plugin-svgr/client" />
    
  3. Restart the app

OR

  1. Add this line of code to your tsconfig.js:

    types": ["vite-plugin-svgr/client"]
    
  2. Restart the app

Personally, I would like to use the first solution.