Typescript: Erro "não é possível compilar namespaces" com --isolatedModules e sem namespaces

Criado em 17 abr. 2017  ·  52Comentários  ·  Fonte: microsoft/TypeScript

Versão do TypeScript: noturno (2.3.0-dev.20170417)

Código

function f() {}

Comportamento esperado:

Nenhum erro ou uma mensagem de erro sobre um arquivo não-módulo em um projeto --isolatedModules .

Comportamento real:

src/a.ts(1,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided.

Isso ocorre porque nós em program.ts verifyCompilerOptions para procurar qualquer arquivo fonte que não seja uma declaração de módulo externo, e falhamos no primeiro, seja ele qual for.
A mensagem de erro deve ser atualizada para refletir o verdadeiro motivo pelo qual emitimos esse erro e não mencionar os namespaces.
Como alternativa, poderíamos apenas permitir arquivos sem importações e realmente procurar um namespace antes de adicionar esse erro.

Bug Error Messages help wanted

Comentários muito úteis

A global file cannot be compiled using '--isolatedModules'. Ensure your file contains imports, exports, or an 'export {}' statement.

Todos 52 comentários

A mensagem de erro precisa ser mais clara. em vez de namespaces pode dizer non-module . @DanielRosenwasser recomendações?

Não deve haver uma mensagem de erro nesta situação. A opção --isolatedModules deveria apenas desligar o sistema de módulo interno completamente, se tsc ainda apresentar erros desta forma, então a opção não fez seu trabalho.

Em # 15839, eu pretendia modificar o comportamento de verificação, mas depois percebi que essa verificação é simplesmente inútil e a solução ideal é removê-la.
O typescript sempre permitiu o uso de namespace dentro de um módulo externo com --isolatedModules em:

export function something() {} // export found, so this module is considered 'external'
namespace ns {} // namespace is still valid in an external module

Portanto, o cheque não está fazendo nada naquele caso (aparentemente inválido), quando deveria reclamar. Então, por que reclamar quando o programador nem mesmo está usando nenhum namespace, não fazendo nada de errado?

@wilonth O motivo desse problema é que a mensagem de erro está errada: os namespaces são perfeitamente adequados se fizerem parte de um módulo (es6), mas qualquer arquivo que não seja do módulo deve ser um erro.

@ andy-ms Eu estava tentando apontar que todo o código para verificar esse erro é inútil e devemos apenas removê-lo em vez de complicar mais o código.
Meu ponto é, quando --isolatedModules está ativado, cada arquivo deve ser considerado um módulo externo (ES6), ponto final. Nesse sentido, o uso de namespaces deve ser legal porque, agora, é perfeitamente legal usar namespaces dentro de módulos ES6 (com --isolatedModules ativado).

Meu ponto é, quando --isolatedModules está ativado, cada arquivo deve ser considerado um módulo externo (ES6), ponto final.

A semântica aqui é que um módulo é um arquivo com pelo menos uma importação ou exportação de nível superior. não importa como você invoca o compilador.

@mhegazy Sim e essa regra é exatamente a raiz do problema que temos aqui. A regra trata injustamente um arquivo sem importação ou exportação como parte do sistema de módulo interno legado, então --isolatedModules rejeita o arquivo.
Agora, não devemos mudar a regra porque isso provavelmente quebrará muitas coisas, mas podemos resolver o problema atual muito facilmente apenas removendo esta mensagem de erro.
Vamos imaginar que esta mensagem de erro "não é possível compilar namespaces" sendo removida, o que pode dar errado? Que tal uma base de código que usa módulo interno, como o próprio compilador Typescript? Com --isolatedModules ativado, ele compilaria em código de lixo e confundiria o usuário? Não, não vai, haveria um monte de mensagens de erro Typescript sobre símbolos indefinidos, porque --isolatedModules quebrou os links entre os arquivos, bastante óbvio de entender.
Você consegue encontrar ALGUMA desvantagem em remover essa mensagem de erro? Eu não pude. Por que não escolheríamos a solução mais fácil, que não envolve trabalho (basta remover as linhas) e não tem desvantagens?

Com --isolatedModules ativado, ele compilaria para lixo código e confundiria o usuário? Não vai

Sim vai.

O objetivo do sinalizador --isolatedModules é validar se um programa pode ser compilado com êxito por meio da transpilação de arquivo único.

A base de código do TypeScript não pode ser compilada com êxito por meio da transpilação de arquivo único. Existe um código como este em todos os lugares:

arquivo1

namespace ts {
  export var x = 10;
}

arquivo2

namespace ts {
  var y = x; // transpiles to ts.x during whole-program compilation
}

Se transpilarmos o arquivo 2 para um único arquivo, ele irá quebrar.

Meu mal, estraguei meus testes. Eu, por meio deste, retiro minha proposta. Obrigado @RyanCavanaugh por lembrar.

Portanto, a solução deve ser: detectar o uso real do namespace antes de enviar essa mensagem de erro (ou seja, a solução "alternativa" que @ andy-ms propôs). Não podemos simplesmente mudar o texto para outra coisa porque uma mensagem de erro neste caso está totalmente errada.
Eu quero fazer um PR, mas ainda posso ser confiável aqui depois de vomitar todas essas merdas?

A global file cannot be compiled using '--isolatedModules'. Ensure your file contains imports, exports, or an 'export {}' statement.

Se transpilarmos o arquivo 2 para um único arquivo, ele irá quebrar.

Desculpe pela necromancia, mas certamente isso deveria, ao direcionar os módulos, falhar com algo como 'x' is not defined ? Esse caso não me parece diferente do trivial:

arquivo1

var x = 10;

arquivo2

var y = x;

Que também funciona na concatenação / avaliação global e não com módulos; nada a ver com namespaces .

Essencialmente, por que o texto digitado se incomoda em adivinhar que os arquivos sem import ou export não são módulos, quando ele já deveria saber da opção do compilador module ? Por exemplo, o próprio Typescript compila sem definir module , portanto, está usando o none padrão, de modo que o compilador pode assumir concatenação / avaliação global.

Ao usar --module <something> e usar declarações não importadas de outros arquivos, (incluindo os próprios namespaces) typescript já irá falhar com "não definido" antes de --isolatedModules , e o mesmo depois com export {} solução alternativa, então isso não parece uma quebra de compatibilidade para remover essa suposição - estou faltando alguma coisa?

Eu percebi que por algum motivo você ainda pode usar import / export com --module none --isolatedModules , o que é bastante confuso, possivelmente um bug?

@DanielRosenwasser como um usuário final: o que significa "Um arquivo global"? Eu gosto da orientação, no entanto. Talvez mais como "Arquivos sem nenhuma instrução de importação ou exportação não são módulos e não podem ser compilados com '--isolatedModules'. Adicione uma instrução 'export {}' se este arquivo for avaliado apenas por seus efeitos colaterais." - embora a linguagem lá não pareça muito mensagem de erro-y.

Estou vendo o mesmo erro para um projeto js simples. Acabei de criar um projeto js de amostra abaixo é o conteúdo dos arquivos de pacote e script. Como posso resolver esse problema?

Package.json
{
"plnkr": {
"runtime": "system"
}
}

lib / script.js
//
// Blackjack
// por Dheeraj Kumar
//

let card1 = "Ás de espadas",
card2 = "dez de copas";

console.log ('Bem-vindo ao Blackjack!');

console.log ("Você recebeu:");
conosle.log ("" + card1);
console.log ("" + card2);

Alguma atualização sobre isso?

Costumo fazer isso em pequenos testes.

describe('jest', () => {
  it('finds this test', () => {
    expect(true).toBeTruthy();
  });

  it('parses this typescript', () => {
    const actual: number = 0;
    const expected: number = 0;
    expect(actual).toEqual(expected);
  });
});

export {
  // Use an empty export to please Babel's single file emit.
  // https://github.com/Microsoft/TypeScript/issues/15230
}

Eu realmente quero uma opção que faça o TypeScript considerar cada arquivo .ts como um módulo ES6, independentemente de conter instruções de importação / exportação ou não. Eu originalmente assumi que a opção --isolatedModules era essa opção, mas ela causa este erro extremamente confuso em arquivos sem importação / exportação. (Ainda não entendo o que a mensagem de erro significa por namespaces. Não acho que estou usando esse recurso.) O motivo pelo qual quero essa configuração é porque tive vários problemas que não foram detectados pelo TypeScript porque fiz referência acidentalmente uma variável de nível superior de um arquivo .ts em outro (que não tinha instruções de importação / exportação, então TypeScript não os tratou como módulos ES6) apesar de usar node / parcel / webpack onde os arquivos não podem fazer referência uns aos outros variáveis ​​não exportadas como essa.

Acabei aqui tentando consertar uma espécie de aborrecimento relacionado. Os comentários abaixo são apenas para ajudar qualquer outro usuário do VS Code a pesquisar sobre esse erro com create-react-app e TypeScript.

Ao configurar um proxy com create-react-app 2.x e TypeScript, você adiciona um arquivo chamado setupProxy.js com código como este:

const proxy = require('http-proxy-middleware');
module.exports = function(app) { /* ... */ };

react-scripts lê este arquivo fora do processo de transpilação ts, então deve ser js simples.

Isso funciona exatamente como documentado , mas tem um efeito colateral irritante.

O tsconfig.json gerado por react-scripts inclui todos os arquivos em src , incluindo setupProxy.js . Como resultado, ele aciona o código VS para mostrar o erro Cannot compile namespaces... em setupProxy.js , marca o código com um rabisco vermelho e inclui-o no painel Problemas. Na minha configuração, ele também destaca o arquivo e todas as suas pastas ancestrais em vermelho.

Solução: suprima a mensagem de erro do código VS excluindo o arquivo setupProxy.js em tsconfig.json.

{
  // ...
  "exclude": ["src/setupProxy.js"]
}

react-scripts força isolatedModules: true , mas não parece substituir exclude .

Alternativa: Adicione uma exportação nomeada a `setupProxy.js:

export const _ = '';

Com uma exportação de nível superior, agora é válido com --isolatedModules.

Muitas vezes, os desenvolvedores recebem essa mensagem porque há arquivos que não deveriam ser incluídos na cópia (gulp.js etc)

ATENÇÃO - Se você estiver usando um app criar-reagir e ver esse problema como eu ... Consegui contornar isso fazendo uma alteração no meu arquivo tsconfig.json ....

Mudando o seguinte

    "isolatedModules": true,

para

    "isolatedModules": false,

@UncleFifi E então o erro passa da verificação de tipo para a transformação do a primeira advertência .

@jtbennett você pode simplesmente não exportar nada com export {}; - a forma degenerada de export { name, localName as exportName };

@UncleFifi E então o erro passa da verificação de tipo para a transformação do a primeira advertência .

Somente se você estiver realmente usando namespaces. Este problema é principalmente sobre este erro reclamar de namespaces que surge quando você nem mesmo está usando namespaces e apenas tem um arquivo legal com importação / exportação.

Somente se você estiver realmente usando namespaces. Este problema é principalmente sobre este erro reclamar de namespaces que surge quando você nem mesmo está usando namespaces e apenas tem um arquivo legal com importação / exportação.

Certo, desculpe - já faz um tempo que eu não li este tópico! Dito isso, a razão pela qual eles definiram --isolatedModules no CRA é porque ele emula de perto as limitações do babel datilografado (uma vez que o babel também é uma transpilação de arquivo único), então você deve pelo menos estar ciente de que está removendo essa proteção. ferroviário.

Portanto, a solução atual para o erro Cannot compile namespaces when --isolatedModules flag is provided é adicionar export {}; na parte superior do arquivo?

Sim, isso resolverá o problema. (Supondo que você não esteja realmente usando TypeScript namespace . Caso contrário, você tem um problema diferente e provavelmente legítimo.)

Acabei de receber esta mensagem devido a um arquivo "vazio" (ou seja, todo o arquivo foi comentado). Estou feliz que o TS pegou isso, mas a mensagem de erro era extremamente opaca (e as cores estavam quebradas em uma instalação vanilla do CentOS 7, mas isso provavelmente devido ao servidor de desenvolvimento do webpack, não relacionado diretamente ao TS)

screen shot 2019-02-06 at 14 20 14

_Editar: não pode reproduzir. Definitivamente, estava olhando para o arquivo que consistia em apenas três exportações de nível superior e tive esse erro, mas antes disso, fiz algo errado em outro lugar._

Este erro aconteceu comigo com um arquivo que tem exportações de nível superior.

// Cannot compile namespaces:
export const foo = 'foo';

// Compiles fine
const foo = 'foo';
export { foo };

@ denis-sokolov Pergunta óbvia: você também tem outras coisas nesse arquivo, como namespaces?

Se for literalmente apenas export const , meu segundo palpite seria que o typescript está sendo usado em algo como webpack com ts-loader e só está vendo o conteúdo após a passagem anterior (por exemplo, babel-loader) que está expandindo export de alguma forma, mas isso é um pouco forçado.

Não consigo mais reproduzi-lo. Desculpe, @simonbuchan , pelo falso alarme.

Não tenho ideia de por que estou recebendo este erro naquele arquivo específico.
Outros arquivos se comportam bem

screen shot 2019-02-18 at 12 49 07
screen shot 2019-02-18 at 12 48 34

Estou em uma situação em que estou usando o CRA TypeScript e importando um pacote que não tem @types . Quero adicionar declare module 'package' para fornecer meus próprios tipos, mas não posso colocar essa instrução em nenhum arquivo de módulo. Então, vou em frente e crio types.ts para colocar a instrução declare module lá. Agora recebo este erro.

Quando eu substituo isolatedModules por false , CRA muda de volta para mim. Isso não é solução.

Quando adiciono export {} ao arquivo types.ts com declare module , obtenho nome de módulo inválido no aumento. em vez de. Este erro é evitado colocando a declaração em um arquivo não-módulo, mas o CRA por meio dessa configuração isolatedModules forçada força cada arquivo a ser um módulo!

Portanto, há um caminho circular para resolver um erro apenas para pousar em outro e voltar. Como isso pode ser resolvido?

@Bnaya em um palpite, os arquivos que funcionam estão usando instruções de importação ou exportação? Use apenas require()/module.exports e import/export em seu código. Caso contrário, verifique se todos os seus arquivos estão cobertos pela inclusão tsconfig (verifique os documentos para obter detalhes completos sobre esse

As declarações do módulo
Eu só fiz CRA adicionar novamente as configurações que removi, não alterá-las de volta, mas talvez seja mais insistente para módulos isolados?

@simonbuchan Eu tentei .d.ts mas também não funcionou para mim, vou relatar o porquê exatamente, não tenho certeza do que era. E, de fato, o CRA reescreveu essa configuração para mim.

@simonbuchan, tentei tudo isso antes - sem sucesso :(

@simonbuchan Hmm ok então .d.ts funciona, posso declarar o módulo lá e digitá-lo. A razão pela qual abandonei originalmente é porque para aquelas tipificações que desejo declarar naquele módulo, preciso fazer referência a outras tipificações, mas introduzir import no arquivo .d.ts faz com que ele pare de funcionar. Não sei como resolver isso, mas é minha falta de conhecimento de TypeScript que não tem mais nada a ver com esse erro.

Aqui está um caso mínimo de reprodução, usando typescript @ next (repo completo em https://github.com/yang/sandbox-ts-namespaces-error):

src / a.js: (aviso, nenhuma palavra-chave de importação / exportação necessária)

module.exports = "hello"; // you could really put anything here, e.g. console.log('hello');

tsconfig.js:

{
  "compilerOptions": {
    "allowJs": true,
    "isolatedModules": true,
    "noEmit": true,
    "strict": true
  },
  "include": ["src"]
}

Erro:

$ ./node_modules/.bin/tsc
src/a.js:1:1 - error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided.

1 module.exports = "hello";
  ~~~~~~


Found 1 error.

Eu também encontrei isso pela primeira vez por meio de create-react-app --typescript , que instrui você a criar um setupProxy.js (ou setupTests.js). CRA também define isolatedModules e allowJs como verdadeiros. Parece não ter sido um problema até uma versão mais recente do texto datilografado (não vi erros sobre setupProxy.js enquanto estava no texto datilografado 3.1.x, apenas depois de atualizar para 3.2.x ou 3.3.x).

A solução alternativa para adicionar arquivos .js ao seu conjunto de exclusão funciona ao executar tsc, mas - irritantemente - você ainda vê erros desses arquivos em editores do serviço de linguagem TS (tentei VS Code e Webstorm). (Este parece ser um problema separado e mais geral com o serviço de linguagem TS não respeitando as exclusões - mas não consegui encontrar um problema existente para isso.) Para mascarar esse erro nos editores, adicionei arquivos .d.ts para os arquivos * .js.

Além disso, exigir ou importar os arquivos .js também torna a exclusão ineficaz, fazendo com que o erro seja gerado (fora do seu editor).

Apenas desabilitar allowJs (contra o que sugere create-react-app) parece estar funcionando para mim.

Continuo recebendo esse erro para meu web worker.

Tentei excluir o arquivo ou pasta individual e não está funcionando para mim.

Se não houver maneira de substituir essa configuração isolatedModules, o CRA continua reescrevendo o tsconfig.json.

Alguma outra sugestão?

@jamespfarrell Coloque export {}; em algum lugar do seu arquivo.

@Macil obrigado pelo seu conselho.

Eu recebo este erro:

Tentativa de erro de importação: './workers/HeartBeat.worker.js' não contém uma exportação padrão (importado como 'HeartBeatWorker').

Se eu adicionar:

export default {};

Eu recebo:

TypeError não capturado: _workers_HeartBeat_worker_js__WEBPACK_IMPORTED_MODULE_2 __. Default não é um construtor

Não há simplesmente uma maneira de contornar esses 'módulos isolados' se não por um arquivo, mesmo para todos os arquivos?

Esses erros que você está obtendo agora não estão relacionados à configuração isolatedModules. Se você desativou os módulos isolados, ainda obterá esses erros.

Tentativa de erro de importação: './workers/HeartBeat.worker.js' não contém uma exportação padrão (importado como 'HeartBeatWorker').

Onde esse erro está acontecendo? Parece que você está tentando importar a exportação padrão de um arquivo que não possui um, como import Foo from './workers/HeartBeat.worker.js'; . Se você não quiser importar uma exportação padrão, altere sua linha de importação para import './workers/HeartBeat.worker.js'; .

Você está certo, era outra coisa @Macil ! obrigado!

_Talvez outra pessoa tenha o mesmo problema: _ Eu tive o mesmo erro aparecendo para alguns arquivos que deixei como espaços reservados sem nenhum conteúdo neles, mas estou importando-os em outros arquivos, ou seja. Eu tinha o arquivo styles.js vazio que foi importado em outro arquivo de componente.

Basta adicionar
image

Eu tive este erro para uma definição de módulo que acidentalmente coloquei como sufixo .ts vez de .d.ts , se alguém mais estiver cometendo esse erro específico. Tem que reiniciar o servidor após consertar.

Mesmo erro. Estou usando CRA

Enfrentei esse problema no CRA. Eu simplesmente esqueci de exportar qualquer coisa do arquivo:
Снимок экрана от 2019-04-22 22-24-04

Então, eu tive este erro porque eu tinha um arquivo .js na pasta raiz do meu projeto, no meu arquivo tsconfig.json eu tinha configurado:

"compilerOptions": {
    ....
  },
  "include": ["src"],

Tive que trocá-lo por isso:

"compilerOptions": {
    ....
  },
  "include": ["src/*"],

Isso resolveu, mas não entendo por que, alguém pode me explicar? Meu entendimento era que incluir src eliminaria os arquivos raiz e pastas irmãs.

@thitemple Você conseguiu esse snippet / * de um artigo em algum lugar? O manual do webpack parece indicar que o primeiro é o correto. Estou diagnosticando um problema semelhante e deparei com sua postagem.

@ vort3xxx eu não fiz. Eu vi esta postagem https://github.com/microsoft/TypeScript/issues/15230#issuecomment -479730947 de @DaviSpindola e tentei. Foi isso

@ vort3xxx eu não fiz. Eu vi este post # 15230 (comentário) de @DaviSpindola e tentei. Foi isso

Mesmo problema, mesma solução. TS 3.5.2.

@ThomasdenH

@simonbuchan Eu tentei .d.ts mas também não funcionou para mim, vou relatar o porquê exatamente, não tenho certeza do que era. E, de fato, o CRA reescreveu essa configuração para mim.

Encontrando exatamente o mesmo problema. Você já descobriu como resolver isso? Definir .ts ou .d.ts arquivos de declaração dentro de um aplicativo create react retorna o erro All files must be modules when the '--isolatedModules flag. Definir o sinalizador como false ou remover a propriedade isolatedModules redefine inteiramente para true ao iniciar a criação do aplicativo de reação.
Adicionar export {} na parte inferior do arquivo de declaração resulta no erro: Invalid module name in augmentation. Module '...' resolves to an untyped module at '...' .

Alguém por favor ajude. Como adiciono arquivos de declaração personalizados a um projeto de aplicativo de criação de reação?

Acabei de descobrir se mais alguém está tendo o mesmo problema. Basta adicionar seus tipos de declaração ao arquivo react-app-env.d.ts na pasta de origem ao usar o aplicativo create react.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

dlaberge picture dlaberge  ·  3Comentários

fwanicka picture fwanicka  ·  3Comentários

zhuravlikjb picture zhuravlikjb  ·  3Comentários

blendsdk picture blendsdk  ·  3Comentários

DanielRosenwasser picture DanielRosenwasser  ·  3Comentários