93 votes

Que signifie "... résout en une entité non modulaire et ne peut pas être importé à l'aide de cette construction"?

J'ai quelques Tapuscrit fichiers:

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();

Cela me donne des erreurs lorsque vous essayez d'utiliser new

Module "MyClass" décide d'un non-module entité et ne peuvent pas être importés à l'aide de cette construction.

et lorsque vous essayez d'appeler fn()

Ne peut invoquer une expression dont le type est dépourvu d'un appel de la signature.

Ce qui donne?

160voto

Ryan Cavanaugh Points 17393

Pourquoi ça ne marche pas

import * as MC from './MyClass';

C'est ES6/ES2015 style import de la syntaxe. La signification exacte de ce qui est "Prendre le module de l'espace de noms de l'objet chargé d' ./MyClass et l'utiliser localement MC". Notamment, le module " espace de noms de l'objet" se compose uniquement d'un simple objet avec des propriétés. Un ES6 module objet ne peut pas être invoquée comme une fonction ou avec new.

Pour le dire encore une fois: Un ES6 module de l'espace de noms de l'objet ne peut pas être invoquée comme une fonction ou avec new.

La chose que vous import l'aide * as X à partir d'un module est défini pour seulement avoir des propriétés. Dans downleveled CommonJS cela pourrait ne pas être pleinement respectés, mais Tapuscrit est vous dire ce que le comportement défini par la norme.

Ce qui fonctionne?

Vous aurez besoin d'utiliser la CommonJS de style à l'importation de la syntaxe d'utilisation de ce module:

import MC = require('./MyClass');

Si vous contrôlez les deux modules, vous pouvez utiliser export default à la place:

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

Je suis Triste à Ce Sujet, les Règles sont Stupides.

Il aurait été agréable à utiliser ES6 importation de la syntaxe, mais maintenant que j'ai à faire c' import MC = require('./MyClass'); chose? C'est tellement 2013! Boiteux! Mais le deuil est une partie normale de la programmation. Veuillez passer à l'étape cinq, dans le Kübler-Ross modèle: l'Acceptation.

Tapuscrit ici est de vous dire ce qui ne fonctionne pas, car il ne fonctionne pas. Il y a des hacks (ajout d'un namespace déclaration d' MyClass est un moyen populaire pour prétendre que cela fonctionne), et ils peuvent travailler aujourd'hui dans votre downleveling module bundler (par exemple cumulatif), mais c'est illusoire. Il n'y a pas ES6 module implémentations dans la nature, mais qui ne sera pas vrai pour toujours.

L'image de votre soi futur, en essayant de s'exécuter sur un neato natif ES6 module de mise en œuvre et de trouver que vous avez vous-même mis en place pour les cas de défaillance majeure, en essayant d'utiliser ES6 syntaxe de faire quelque chose qui ES6 explicitement ne pas le faire.

Je veux profiter de ma non-standard chargeur de module

Peut-être que vous avez un chargeur de module que "utilement" crée default des exportations lorsqu'il n'en existe aucun. Je veux dire, les gens font des normes pour une raison, mais en ignorant les normes est amusant parfois, et on peut penser que c'est une chose sympa à faire.

Changement MyConsumer.ts :

import A from './a';

Et de préciser l' allowSyntheticDefaultImports de la ligne de commande ou tsconfig.json option.

Notez que allowSyntheticDefaultImports ne change pas le comportement d'exécution de votre code. C'est juste un indicateur qui indique à la Machine que votre chargeur de module crée default des exportations lorsqu'il n'en existe aucun. Il ne sera pas magiquement de rendre votre code de travail en nodejs quand il n'en a pas avant.

25voto

Michael Points 1971

Tapuscrit 2.7 présente la prise en charge par l'émission de nouvelles méthodes d'assistance: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form-commonjs-modules-with---esmoduleinterop

Donc, dans le tsconfig.json ajouter ces deux paramètres:

{
    // Enable support for importing CommonJS modules targeting es6 modules
    "esModuleInterop": true,

    // When using above interop will get missing default export error from type check since
    // modules use "export =" instead of "export default", enable this to ignore errors.
    "allowSyntheticDefaultImports": true
}

Et maintenant, vous pouvez utiliser:

import MyClass from './MyClass';

6voto

Sash Points 188

Ajout de mes 2 cents ici au cas où quelqu'un d'autre aurait ce problème.

Ma façon de contourner le problème sans modifier tsconfig.json (ce qui peut être problématique dans certains projets), consiste simplement à désactiver la règle pour la connexion en ligne.

import MC = require('./MyClass'); // tslint:disable-line

5voto

NSjonas Points 1457

J'ai eu cette erreur en essayant d'inclure un paquet npm debounce dans mon projet.

Lorsque j'ai essayé la solution acceptée ci-dessus, j'ai eu une exception:

L'affectation d'importation ne peut pas être utilisée lorsque vous ciblez des modules ECMAScript. Envisagez d'utiliser "import * as ns de" mod "", "importer {a} de" mod "", "importer d de" mod "" ou un autre format de module.

Cela a fini par fonctionner:

 import debounce from 'debounce' 
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X