Introdução: quando o compilador diz «não»
\nVocê abre seu editor favorito, escreve algumas linhas de código em TypeScript, inicia a compilação — e de repente vê isto: 'React' refere-se a um global UMD, mas o arquivo atual é um módulo. Se você já encontrou esse erro, sabe o quão desconcertante ele pode ser. Aparentemente está tudo certo: a importação existe, o React está instalado, mas o compilador teimosamente se recusa a entender o que você quer.
Este erro não é apenas um bug aleatório. Ele revela mecanismos profundos de funcionamento do TypeScript, sistemas de compilação e formatos modulares. Neste artigo, não vamos apenas mostrar como corrigi-lo. Vamos olhar «por baixo do capô» e entender por que ocorre o erro React refere-se a um global UMD, como o TypeScript diferencia UMD e ESM, e como configurar corretamente seu projeto para esquecê-lo para sempre.
\n\nO artigo é voltado para desenvolvedores que já conhecem React e TypeScript, mas querem entender os bastidores. Prontos? Vamos lá!
\n\nO que é UMD e por que o TypeScript sabe sobre ele?
\n\nAntes de analisar o erro, vamos lembrar o que são formatos modulares em JavaScript. Quando você escreve import React from 'react', o TypeScript precisa entender de onde vem esse código e como usá-lo. Existem vários padrões:
- \n
- ESM (ECMAScript Modules) — padrão moderno que usa
import/export. \n - CommonJS — formato do Node.js com
require/module.exports. \n - UMD (Universal Module Definition) — híbrido que funciona tanto no navegador (através de variáveis globais) quanto no Node.js (através de módulos). \n
O React é distribuído em vários formatos, incluindo UMD. Quando você instala o React via npm, você obtém a versão ESM (por exemplo, index.js com export default). Mas versões antigas ou algumas compilações podem usar UMD, onde o React está disponível como uma variável global window.React.
O TypeScript analisa arquivos de declaração de tipos (.d.ts). Para o React, isso é o pacote @types/react. Dentro dele, há uma declaração que indica: «React está disponível como um global UMD». Quando o TypeScript vê que seu arquivo está marcado como módulo (por exemplo, contém import ou export), ele começa a ficar confuso: «Você está importando React, mas na declaração está dito que é um global. E o arquivo é um módulo. Como proceder?»
Por que ocorre o erro: «React refere-se a um global UMD, mas o arquivo atual é um módulo»?
\n\nO erro aparece quando o TypeScript não consegue determinar de forma inequívoca como processar a importação do React. Aqui está um cenário típico:
\n\n// App.tsx\nimport React from 'react';\nimport { useState } from 'react';\n\nconst App: React.FC = () => {\n const [count, setCount] = useState(0);\n return <div>{count}</div>;\n};\n\nexport default App;\n\n\nVocê inicia a compilação, e o TypeScript exibe o erro: 'React' refere-se a um global UMD, mas o arquivo atual é um módulo. Considere adicionar uma importação.
Por quê? Porque em @types/react existe esta declaração (simplificada):
// no arquivo index.d.ts de @types/react\nexport = React;\nexport as namespace React;\n\ndeclare namespace React {\n // ...tipos\n}\n\n\nA linha chave é export as namespace React. Ela diz ao TypeScript: «Este módulo também está disponível como uma variável global React (UMD)». Quando seu arquivo é um módulo (contém export), o TypeScript pode não entender se você quer usar o React global ou o importado. O resultado é um conflito.
Como corrigir: três maneiras comprovadas
\n\nManeira 1: Importação explícita (a mais comum)
\n\nA maneira mais simples é garantir que você importe o React explicitamente, mesmo que