38

Import statements in TypeScript: which syntax to use

 5 years ago
source link: https://www.tuicool.com/articles/hit/MbaaQjM
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

TypeScript has multiple different syntaxes for imports. When should you use which?

Most of the time, the module exports multiple things

There are two great ways to import from another module in TypeScript, when the module exports an object with properties. This is the common case.

Import the whole module, giving it a name:

import * as child_process from "child_process";

// then later...
child_process.spawn(...);

or pick the names you want to import:

import { spawn } from "child_process";

// then later
spawn(...);

When the module exports just one thing

This doesn’t work when the module doesn’t export an object with properties. Some modules export a function or a class instead.

How can you know? Good question. You have to look at the module’s code or look at examples.

In this case, give the single exported thing a name:

import boxen from "boxen";

// then later... 
// boxen happens to export a function
boxen(...);

How to know what the JavaScript module exports

The short answer is, try both the “import * as blah” and the “import blah” syntaxes and see which works.

Sometimes you can look at examples and see how they use the export. These can be hard to translate from JS. For instance, in the npm page for boxen it shows:

const boxen = require('boxen');
 
// then later
boxen('unicorn', {padding: 1});

This shows that the thing it gets from requiring the module is being used as a function. So, it’s a single function. Use import boxen as "boxen";

In contrast, the npm page for chalk shows:

const chalk = require('chalk');
 
console.log(chalk.blue('Hello world!'));

Here, you can see that the thing it got from requiring boxen is being used as an object. Use import * as chalk from "chalk";

How to know what the TypeScript module exports

A TypeScript module can say export default myFunction to export just one thing. Use import myFunction from "./myModule" to bring it in.

More commonly, TypeScript modules say export myFunction in which case myFunction will be one of the properties on the exported object. Use import * as myModule from "./myModule" or import { myFunction } from "./myModule" to bring it in.

Do I have to name it after the module?

No, there’s nothing stopping you from naming your import whatever. You can import booger from "boxen" and then call booger("put this in a box") . This seems ridiculous.

When the module exports an object it is not so ridiculous. With lodash:

import * as _ from "lodash";

_.groupBy(...);

See, here the methods etc on the imported object all have the names assigned by the module author, so it doesn’t matter if I name the module object itself something cute.

Am I importing a module or a package?

If the import starts with “.” then it’s a relative import, and it’s a module. (A module is a file.) Otherwise, it’s conceptually a package, but really it’s the top-level module within the package. The top-level module is usually the package’s index.js , but that can be overridden in the main element of the package's package.json file.

This other weird case

I haven’t hit this yet, but the docs say that sometimes from TS people do:

export = Thing;

to export just one thing instead of an object. In this case, you have to bring that in with:

import thing = require("./Thing");

This seems to be for historical reasons for interop in ways you probably don’t need, so let’s not.

Fall back to JS

You can always const thing = require("Anything"); just like in JS, but you won't get typing. You also won't get compile-time checking that the module is available. Sometimes that is what you want.

Sometimes ‘import’ means ‘run’

You can import a script for side effects only:

import "./set_up_global_logging";

How do you really feel, Jess?

Can we all just export an object, please? That way the properties have the name we give them instead of whatever name people assign them. I don’t like default exports. But some people do, and if I want to use their packages then I’ll deal with it. But I’m sad; I wish I could use import * as module from "module" all the time.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK