web-dev-qa-db-fra.com

Une importation de style d'espace de noms ne peut pas être appelée ou construite et entraînera un échec lors de l'exécution.

Il se passe des choses étranges ici, avec TypeScript 2.7.2, dans VSCode version 1.21 avec @ types/express et le code qui suit, dans certains cas, VSCode renvoie des erreurs indiquant qu '"une importation de style espace de noms ne peut pas être appelée ou construite, et entraînera une échec au moment de l'exécution. " Cependant, sur d’autres machines avec des configurations similaires et des fichiers tsconfig.json similaires, le code ne fonctionne que .. Ce qui se passe ici:

import { Bank } from './Bank';
import * as Express from 'express';  <== errors here..

let app: Express.Express;
this.app = Express();                <== and here

Pourquoi cela arrive-t-il?

TIA,

John.

27
John Gorter

L'erreur ne devrait arriver qu'avec esModuleInterop: true. Peut-être que VSCode ignore votre tsconfig.json ou un autre avec esModuleInterop: true est utilisé.

Pour un correctif définitif, définissez l’option du compilateur esModuleInterop sur true et utilisez import express au lieu de import * as express.

Le problème :

La spécification ES6 définit la notion "d'objet d'espace de nom". Un objet d'espace de nom est namespaceObject dans cette instruction: import * as namespaceObject from 'a-module'. Le typeof cet objet est object, vous n'êtes pas censé pouvoir l'appeler.

Vous utilisiez import * as express jusqu'à présent, car express est un module CommonJS. Pour Node.js, il est exporté à l'aide de module.exports. Cependant, il est illégal dans la spécification ES6 et TypeScript vous en avertit maintenant.

La solution :

Si vous définissez esModuleInterop sur true, TypeScript encapsulera vos appels import pour vérifier si le module est un module ES6 ou un CommonJS. Si c'est un module CommonJS et que vous utilisez import default from 'module' TypeScript le trouvera et retournera le bon module CommonJS.

De la note de version TypeScript :

Remarque: Le nouveau comportement est ajouté sous un drapeau pour éviter les ruptures injustifiées dans les bases de code existantes. Nous vous recommandons vivement de l’appliquer aux projets nouveaux et existants. Pour les projets existants, les importations d'espaces de noms (import * en tant qu'express de "express"; express ();) devront être converties en importations par défaut (import express de "express"; express ();).

57
fathy