typescript - En import i namnrymdsstil kan inte anropas eller konstrueras, och kommer att orsaka ett fel vid körning
Med TypeScript 2.7.2, i VSCode version 1.21 med @types/express och koden som följer, i vissa fall visar VSCode fel som säger att
A namespace-style import cannot be called or constructed, and will cause a failure at runtime.
Men på andra datorer med liknande uppsättningar och liknande tsconfig.json-filer fungerar koden bara. Vad händer här...
import { Bank } from './Bank';
import * as Express from 'express'; <== errors here..
let app: Express.Express;
this.app = Express(); <== and here
Varför händer detta?
TIA,
John.
Svar #1
Felet bör bara inträffa med esModuleInterop: true. Kanske ignorerar VSCode din tsconfig.json eller så används en annan med esModuleInterop: true.
För en definitiv lösning, ställ in kompilatoralternativet esModuleInterop till true och använd import express istället för import * as express.
Problemet :
Specifikationen för ES6 definierar begreppet "namespaceobjekt". Ett namespaceobjekt är namespaceObject i detta uttalande: import * as namespaceObject from 'a-module'. typeof på detta objekt är object, du ska inte kunna anropa det.
Du använde import * as express hittills eftersom express är en CommonJS-modul, för Node.js exporteras den med module.exports. Men det är olagligt enligt ES6-specifikationen, och TypeScript varnar dig nu.
Lösningen :
Att sätta esModuleInterop till true kommer göra att TypeScript kapslar in dina import-anrop för att kontrollera om modulen är en ES6-modul eller en CommonJS. Om det är en CommonJS-modul och du använder import default from 'module' kommer TypeScript att ta reda på det och returnera rätt CommonJS-modul.
Från TypeScript-utgivningsanteckningen:
Observera: Det nya beteendet har lagts till under en flagga för att undvika oönskade brytningar i befintliga kodbaser. Vi rekommenderar starkt att det appliceras både på nya och befintliga projekt. För befintliga projekt måste namespace-importer (import * as express from "express"; express();) konverteras till standardimporter (import express from "express"; express();).
Svar #2
I mitt fall hade jag redan "esModuleInterop": true aktiverat i tsconfig.json. Jag behövde konvertera:
import * as assert from "assert";till :
import assert from "assert";