TypeScript and ES6 import syntax

When I started using TypeScript for my Angular applications, I was confused about all the different ways with which you could import other modules.

import './polyfills.ts';
import { Component } from '@angular/core';
import HomeComponent from './pages/home/home-page.component';
import * as _ from 'lodash';
import assert = require('assert');

At first, I thought that as a programmer you could choose whether you wanted to use curly braces or not, but I quickly found out that that was not the case. It all depends on how the module that you are importing is structured.

I have created an overview of the different ways by which a module can be exported, together with their corresponding import syntax. Most of them are actually plain ECMAScript 2015 (ES6) module syntax that TypeScript uses as well.

The examples are from my solution to the first puzzle of Advent of Code 2016 and can be found on GitHub if you want to play around with imports and exports yourself.

Named exports (TypeScript, ES6)

Export syntax

When a module needs to export multiple variables, it can use so-called named exports:

Another way that named exports can be done is by specifying what you want to export at the end of the module:

Import Syntax

You can import these modules in two ways. Either you import everything as one object (sometimes called namespace):

Or, you specify all the individual variables that you want to import:

If you specify the variables, you can also import them under a different name:

Default export (TypeScript, ES6)

A module can also export one variable as the default export:

This can be imported with the following syntax, without curly braces:

This is implemented by exposing a named export with a special name ‘default’, so you could also do the following:

If you need this to import a module that has both a default export and named exports, then this module might not have one single responsibility.

Empty import (TypeScript, ES6)

Some modules do not export any variables and only have side-effects, such as mutating the global window (global variables) or prototypes (e.g. polyfills). To execute the body of these modules, they can be imported without specifying any variable names. It will be executed only once, because modules in JavaScript are singletons.

NodeJS modules (TypeScript)

NodeJS modules are based on the CommonJS module standard (exports and require), augmented with some NodeJS specific syntax (module.exports for instance).

In JavaScript, you can export things from your module by assigning them to the object exports and import then synchronously with require()

This is also valid TypeScript, but the TypeScript compiler cannot help you with type information from the module. For this to work, you need to import the module, to let TypeScript find the type information from the module’s type definition file.

If you let TypeScript compile to CommonJS modules, you can also use ES6 module syntax in your TypeScript source. However, because it has no default export, you have to import it as with named exports:

More information

I hope this gives you an overview on how you should import the different module flavours in ES6 and TypeScript. For more details, have a look at the following resources that I’ve used to make this overview.

The very precise and thorough book “Exploring ES6” by Axel Rauschmayer

The official TypeScript handbook

Leave a Reply

Your email address will not be published. Required fields are marked *