Tenho alguns arquivos TypeScript:
MyClass.ts
class MyClass {
constructor() {
}
}
export = MyClass;
MyFunc.ts
function fn() { return 0; }
export = fn;
MyConsumer.ts
import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();
Isso me dá erros ao tentar usar new
O módulo "MyClass" é resolvido como uma entidade não módulo e não pode ser importado usando esta construção.
e ao tentar ligar fn()
Não é possível invocar uma expressão cujo tipo não tem assinatura de chamada.
O que da?
typescript
ecmascript-6
es6-modules
Ryan Cavanaugh
fonte
fonte
javascript
como uma tag primária e sairecmascript-6
, porque a tag primária aqui étypescript
. A questão assume erroneamente queexport =
(um recurso TS) pode ser emparelhado comimport ... from
, embora deva ser emparelhado comimport =
. É basicamente importação / exportação de módulo ES6 vs CJS / AMD.Respostas:
Por que não funciona
Esta é a
import
sintaxe do estilo ES6 / ES2015 . O significado exato disso é "Pegue o objeto de namespace do módulo carregado de./MyClass
e use-o localmente comoMC
". Notavelmente, o " objeto de namespace do módulo " consiste apenas em um objeto simples com propriedades. Um objeto de módulo ES6 não pode ser chamado como uma função ou comnew
.Repetindo : um objeto de namespace do módulo ES6 não pode ser invocado como uma função ou com
new
.A coisa que você está
import
usando* as X
em um módulo é definido para ter apenas propriedades. Em CommonJS de nível inferior, isso pode não ser totalmente respeitado, mas o TypeScript está dizendo a você qual é o comportamento definido pelo padrão.O que funciona?
Você precisará usar a sintaxe de importação do estilo CommonJS para usar este módulo:
Se você controlar os dois módulos, você pode usar
export default
:MyClass.ts
MyConsumer.ts
Estou triste com isso; As regras são mudas.
Teria sido bom usar a sintaxe de importação ES6, mas agora eu tenho que fazer isso
import MC = require('./MyClass');
? É tão 2013! Lame! Mas o luto é uma parte normal da programação. Por favor, pule para o estágio cinco no modelo Kübler-Ross: Aceitação.O TypeScript aqui está dizendo que isso não funciona, porque não funciona. Existem hacks (adicionar uma
namespace
declaração aMyClass
é uma forma popular de fingir que isso funciona) e eles podem funcionar hoje em seu bundler de módulo de downlevel específico (por exemplo, rollup), mas isso é ilusório. Ainda não existem implementações de módulo ES6 disponíveis, mas isso não será verdade para sempre.Imagine seu futuro, tentando executar em uma implementação de módulo ES6 neato nativo e descobrindo que você se preparou para uma falha grave ao tentar usar a sintaxe ES6 para fazer algo que o ES6 explicitamente não faz .
Quero aproveitar as vantagens do meu carregador de módulo não padrão
Talvez você tenha um carregador de módulo que "utilmente" cria
default
exportações quando não existem. Quer dizer, as pessoas fazem padrões por uma razão, mas ignorar padrões é divertido às vezes e podemos achar que é uma coisa legal de se fazer.Altere MyConsumer.ts para:
E especifique a
allowSyntheticDefaultImports
linha de comando outsconfig.json
opção.Observe que
allowSyntheticDefaultImports
não muda o comportamento do tempo de execução do seu código. É apenas um sinalizador que informa ao TypeScript que o carregador de módulo criadefault
exportações quando não existem. Ele não fará seu código funcionar magicamente em nodejs quando não funcionava antes.fonte
export = MyClass
? Minha única opção é definir meu módulo comocommonjs
e continuar a tornar o mundo um lugar pior por não usar o ES moderno?--esModuleInterop
, diz "É altamente recomendável aplicá-lo a projetos novos e existentes". Em minha opinião, esta resposta (e a política / entrada do FAQ nosDefinitelyTyped
links aqui) deve ser modificada para refletir a nova postura.TypeScript 2.7 apresenta suporte emitindo novos métodos auxiliares: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-with --- esmoduleinterop
Portanto, em tsconfig.json, adicione estas duas configurações:
E agora você pode usar:
fonte
esModuleInterop
, useiresolveJsonModule
junto com sua outra sugestão de usoallowSyntheticDefaultImports
e funcionou para mim.Adicionando meus 2 centavos aqui caso outra pessoa tenha esse problema.
Minha maneira de contornar o problema sem modificar
tsconfig.json
(o que pode ser problemático em alguns projetos), simplesmente desativei a regra para oneline.import MC = require('./MyClass'); // tslint:disable-line
fonte
Recebi este erro ao tentar incluir um pacote de debounce npm em meu projeto.
Quando tentei a solução aceita acima, obtive uma exceção:
Isso acabou funcionando:
fonte