Импорт типа пространства имен не может быть вызван или сконструирован и приведет к сбою во время выполнения

Странные вещи, происходящие здесь, с TypeScript 2.7.2, в VSCode версии 1.21 с помощью @types/express и последующего кода, в некоторых случаях VSCode выдает ошибки, заявляя, что "импорт типа пространства имен не может быть вызван или сконструирован и вызовет сбой во время выполнения ". Однако на других машинах с аналогичными настройками и аналогичными файлами tsconfig.json код просто работает. Что здесь происходит:

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

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

Почему это происходит?

ТИА,

Джон.

Ответ 1

Ошибка должна произойти только с esModuleInterop: true. Возможно, VSCode игнорирует ваш tsconfig.json или другой с помощью esModuleInterop: true используется значение esModuleInterop: true.

Для окончательного исправления установите для параметра компилятора esModuleInterop значение true и используйте import express вместо import * as express.

Проблема:

Спецификация ES6 определяет понятие "объект пространства имен". Объектом namespaceObject имен является namespaceObject в этом выражении: import * as namespaceObject from 'a-module'. typeof этот объект является object, вы не должны быть в состоянии назвать его.

Вы использовали import * as express до сих пор, потому что express - это модуль CommonJS, для Node.js он экспортируется с использованием module.exports. Однако это незаконно в спецификации ES6, и TypeScript теперь предупреждает вас.

Решение:

Установка esModuleInterop в значение true приведет к тому, что TypeScript esModuleInterop ваши вызовы import чтобы проверить, является ли модуль модулем ES6 или CommonJS. Если это модуль CommonJS, и вы используете import default from 'module' TypeScript обнаружит и вернет правильный модуль CommonJS.

Из примечания к выпуску TypeScript:

Примечание. Новое поведение добавляется под флагом, чтобы избежать необоснованных перерывов в существующих базовых кодах. Мы настоятельно рекомендуем применять его как к новым, так и к существующим проектам. Для существующих проектов импорт имён импорта (импорт * как экспресс из "экспресс"; express();) должен быть преобразован в импорт по умолчанию (import express из "express"; express();).