Incapaz de importar arquivos svg no texto datilografado

109

Em typescript(*.tsx)arquivos, não consigo importar o arquivo svg com esta declaração:

import logo from './logo.svg';

Transpiler diz: [ts] cannot find module './logo.svg'. Meu arquivo svg é justo <svg>...</svg>.

Mas no .jsarquivo posso importá-lo sem problemas com exatamente a mesma instrução de importação. Suponho que tenha algo a ver com o tipo de arquivo svg que deve ser definido de alguma forma para transpiler ts.

Você poderia compartilhar como fazer isso funcionar em arquivos ts?

AngryBoy
fonte
2
Os arquivos svg não são javascript e não podem ser usados ​​como os módulos javascript. Você deve carregar esses arquivos usando uma solicitação http.
toskv
1
Você está usando o Webpack? Essa é a única coisa que vi entender essa importafirmação. Talvez o Webpack seja o que está permitindo isso em seu JavaScript, mas não está fazendo a mesma mágica em arquivos TypeScript. (Não acho que o TypeScript em si saiba o que fazer aqui.)
user94559
1
Se você estiver usando o Webpack, provavelmente precisará compartilhar a configuração do Webpack para obter mais ajuda.
user94559
2
Lendo um pouco mais sobre isso, você provavelmente pode fazer const logo = require("./logo.svg");ou simplesmente ignorar o erro. (Acredito que o TS ainda deve estar exibindo o código correto.)
user94559
Muito obrigado! requer funciona bem! No meu caso, tem que ser const logo = require("./logo.svg") as string;
AngryBoy

Respostas:

184

Se você usar o webpack, poderá fazer isso criando um arquivo de tipos personalizados.

Crie um arquivo denominado custom.d.ts com o seguinte conteúdo:

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

Adicione o custom.d.tsa tsconfig.jsoncomo abaixo

"include": ["src/components", "src/custom.d.ts"]

Fonte: https://webpack.js.org/guides/typescript/#importing-other-assets

Graham
fonte
36
Provavelmente, você precisará adicioná-lo à includeseção em tsconfig.json .
Frederik Krautwald
12
Obrigado! Eu sabia que deveria estar incluído em algum lugar, mas não consigo imaginar onde. Até eu pensei que fosse em tsconfig.json mas não sabia como fazer. Agradeço seu comentário. Fiz uma pesquisa e encontrei:"files": [ "custom.d.ts" ]
Shil Nevado
5
Você pode obter a verificação de tipo do componente JSX digitando o conteúdo:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt
É possível fazer com que o custom.d.tsarquivo funcione globalmente para que o SVG fique em um diretório diferente do custom.d.tsarquivo? Recebo um erro "não é possível encontrar o módulo", a menos que ele esteja no mesmo diretório.
Nic Scozzaro
1
Isso não importa o conteúdo do arquivo em Angular, mas o nome do arquivo como uma string. Eu preciso do conteúdo. Como obtemos o conteúdo do arquivo?
Routhinator
37

Obrigado smarx por apontar o uso require(). Então, no meu caso, deveria ser:

const logo = require("./logo.svg") as string;

que funciona bem em arquivos * .tsx

AngryBoy
fonte
5
logopode ter um nome melhor logoPath, porque é assim que se transforma.
DharmaTurtle de
2
@DharmaTurtle Acho que isso pode ser debatido. Além disso, é chamado logona pergunta, portanto, é uma resposta melhor para esta pergunta específica como está.
ArneHugo
17

Adicione um custom.d.tsarquivo (eu o criei no caminho raiz do meu diretório src) com o tipo correto (graças a RedMatt ):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

Instale svg-react-loader ou algum outro , então:

  • Use-o como o carregador svg principal
  • Ou, se você estiver migrando uma base de código e não quiser tocar na parte de trabalho (JS), especifique o carregador na importação:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Em seguida, basta usá-lo como uma tag JSX:

function f() { 
  return (<MySVG />); 
}
Allenaz
fonte
4

A solução que encontrei: No projeto ReactJS, no arquivo react-app-env.d.ts você apenas remove o espaço no comentário como:

Antes

// / <reference types="react-scripts" />

Depois de

/// <reference types="react-scripts" />

Espero te ajudar

Jilvanx
fonte
Para as pessoas que estão usando o app create-react-app e eslint configurado, isso pode resolver o problema
Daniel Chin
2

Eu tive o mesmo problema ao tentar um tutorial REACT + datilografado.
O que funcionou para mim foi a seguinte instrução de importação.

import * as logo from 'logo.svg'

Aqui estão minhas dependências em package.json.

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

Espero que ajude alguém.

Kiran Mohan
fonte
0

Existe uma maneira alternativa de fazer isso que implementamos: crie seus componentes SVGs. Eu fiz isso porque me incomodou que eu estava usando requiredeclarações commonJS junto com o meu imports.

endymion1818
fonte
0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

se você estiver usando o slint do puglin pode ser que ele tenha desativado pensando que era um comentário mas não para ler o svg você precisa deste tipo de módulo de script apenas desative a linha e fique feliz

Breno Melo
fonte
0

Para usar n ativos no código com TypeScript , precisamos adiar o tipo para essas importações . Isso requer um arquivo custom.d.ts que significa definições personalizadas para TypeScript em nosso projeto.

Vamos configurar uma declaração para arquivos .svg:

custom.d.ts

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

Aqui, declaramos um novo módulo para SVGs especificando qualquer importação que termine em .svg e definindo o conteúdo do módulo como any.

Mehadi Hassan
fonte