Node.js + TypeScript: Unclear syntax with type script compiled code

Shikloshi picture Shikloshi · Dec 29, 2015 · Viewed 15.4k times · Source

I'm trying to work with TypeScript in my node project, but I have some issues with that.

This is my index.ts file:

import express from 'express';

const app = express();

I'm running:

tsc --module commonsjs -d index.ts

My output is index.js:

var express_1 = require('express');
var app = express_1["default"]();

Where did this ["default"] came from? It is making my code not to run properly:

var app = express_1["default"]();
                              ^

TypeError: express_1.default is not a function

As far as I understand, I should have got the code without the "default" brackets and it would have worked fine - I tried removing the brackets and it worked.

What am I missing here?

Answer

dvlsg picture dvlsg · Dec 30, 2015

The safest solution would be:

import express = require('express');

This transpiles to:

var express = require('express');

The official documentation for import require declarations can be found here.

I believe TypeScript expects an export named "default" to function as your code above, judging from the final paragraph here.


Side note: It looks like TypeScript's newest version ([email protected] at the time of writing) will throw a warning on a compile attempt which would attempt to use a missing default:

index.ts(1,8): error TS1192: Module '"express"' has no default export.

Side note 2: An example from Microsoft using the import * as express from 'express'; syntax can be found here. When targeting a module of commonjs (as they are in this example), this will also transpile to var express = require('express');.


If you have at least TypeScript 2.7 and are targeting CommonJS, you can use esModuleInterop, as well.

From the link:

To give users the same runtime behavior as Babel or Webpack, TypeScript provides a new --esModuleInterop flag when emitting to legacy module formats.

Under the new --esModuleInterop flag, these callable CommonJS modules must be imported as default imports like so:

import express from "express";

let app = express();

We strongly suggest that Node.js users leverage this flag with a module target of CommonJS for libraries like Express.js, which export a callable/constructable module.