Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 563
Shikloshi Avatar asked Dec 29 '15 22:12

Shikloshi


People also ask

Can we use TypeScript and JavaScript together?

The TypeScript compiler supports a mix of JavaScript and TypeScript files if we use the compiler option --allowJs : TypeScript files are compiled. JavaScript files are simply copied over to the output directory (after a few simple type checks).

Can I use TypeScript and JavaScript in the same project?

You can use thousands of existing JavaScript libraries in your TypeScript project. Type definition files allow you to enjoy the type-checking and autocomplete features in libraries that were written in JavaScript. These files make you more productive in writing code.

Can we use TypeScript with Express?

Installing TypeScript Along with it, we'll install the the @types declaration packages for Express and Node. js, which provide type definitions in the form of declaration files. Declaration files are predefined modules that describe the shape of JavaScript values, or the types present, for the TypeScript compiler.


2 Answers

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.

like image 110
dvlsg Avatar answered Sep 28 '22 05:09

dvlsg


I solved this by adding the following to tsconfig.json:

{   "compilerOptions": {     ...      "module": "commonjs",     "esModuleInterop": true,     ...   } } 

The esModuleInterop flag is described as: "Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility."

https://www.typescriptlang.org/docs/handbook/compiler-options.html

like image 43
Liam Avatar answered Sep 28 '22 07:09

Liam