Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
A manipulação de imagens em projetos React com TypeScript muitas vezes vira uma dor de cabeça por causa da tipagem e do comportamento do Webpack. Uma questão recorrente é a incompatibilidade entre o tipo esperado pelo atributo 'src' de uma tag <img> e o que as importações de imagens retornam.
Em muitos casos, ao importar uma imagem, o TypeScript gera um erro na hora de usar a variável no atributo 'src' de uma tag <img>. Por padrão, o TypeScript define que o 'src' deve ser de tipo string ou undefined, mas ao importar uma imagem com import * as Logo from 'assets/images/logo.png', o que se obtém de fato é uma referência ao módulo, não uma string direta. A decisão fica mais saudável quando o time consegue medir o impacto depois.
Isso causa erros como: '[ts] Types of property 'src' are incompatible', pois o import retorna um objeto do tipo 'typeof import("*.png")', que não é uma string.
O core da questão está na definição de tipos para arquivos de imagem. O TypeScript, por padrão, não sabe como tratar esses imports, porque eles não são nativos do JavaScript. Para resolver isso, é necessário informar ao TypeScript como interpretar esses arquivos.
A solução mais comum é criar declarações de módulo específicas, que dizem ao TypeScript que qualquer importação de um arquivo com extensão .png, .jpg, etc., deve ser tratada como uma string, ou seja, o caminho do arquivo após o build. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte.
#### 1. Declaração de Módulo Simples
A mais básica e direta é criar um arquivo de declarações, como 'custom_typings/index.d.ts', contendo: Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois.
declare module "*.png" {
const value: string. export default value. }
Essa abordagem faz com que o import seja interpretado como uma string, eliminando o erro, porém, ela não garante a validação de tipos mais específicos. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
#### 2. Uso de 'export =' ao invés de 'export default'
Para uma checagem de tipos mais precisa, a melhor estratégia é usar a declaração:
declare module "*.png" {
const value: any. export = value. } Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
Assim, o import retorna um valor de qualquer tipo, e você pode fazer um cast explícito, por exemplo: Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta.
import Logo from 'assets/images/logo.png'. // Cast para string
const logoSrc: string = Logo as string. // Uso na tag
<img src={logoSrc} alt="" /> A decisão fica mais saudável quando o time consegue medir o impacto depois. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar.
Essa abordagem garante maior flexibilidade e segurança, especialmente se o Webpack estiver configurado para retornar o caminho como string. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. A decisão fica mais saudável quando o time consegue medir o impacto depois. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. A decisão fica mais saudável quando o time consegue medir o impacto depois. A decisão fica mais saudável quando o time consegue medir o impacto depois. A decisão fica mais saudável quando o time consegue medir o impacto depois.
#### 3. Modificar o arquivo de declarações para remover ou alterar a exportação
Outra alternativa é editar o arquivo 'd.ts' para remover ou ajustar a exportação, dependendo da necessidade. Entretanto, essa estratégia pode gerar inconsistências. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Sem esse critério, a solução pode parecer simples no começo e cara no suporte.
1. Criar ou ajustar o arquivo de declarações de tipos para arquivos de imagem.
2. Garantir que o import está correto, preferencialmente usando import padrão:
import Logo from 'assets/images/logo.png'.
3. Fazer um cast explícito para string ao usar na tag <img>:
<img src={Logo as string} alt="" />
4. Testar em ambientes diferentes para verificar se o Webpack está retornando os caminhos corretos.
Por fim, essa questão mostra como configurações de build, tipagem e boas práticas de importação se entrelaçam. Quando bem ajustadas, evitam dores de cabeça e aumentam a confiabilidade do código. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
Se você já passou por isso, qual foi sua solução mais eficiente? Ou, será que há uma abordagem que evita esse tipo de conflito desde o início? Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta.
Eu faria uma validação na build pra verificar se o caminho gerado é mesmo uma string, assim evita surpresa depois.
Acho que o ponto mais importante é cuidar para que o Webpack esteja configurado pra retornar o caminho como string. Sem isso, as declarações de tipos ficam meio que na sorte. Já passei por isso e a dica do 'export =' ajudou muito aqui.
No meu projeto, a maior dor é manter a consistência na importação.
Concordo, Gabriel. Além disso, acho importante documentar esses detalhes na equipe, pq às vezes uma mudança na configuração do Webpack ou TypeScript passa batido e dá problema na hora de produzir.