How to transform require into import statement for third party library?
Asked Answered
F

2

5

In my typescript project I use:

const program = require('commander');
const figlet = require('figlet');
const AWS = require('aws-sdk');

and I want to refactor those lines to work via import instead in order to adhere to tslint's no-var-requires rule. Yet the way it supposed to work eludes me.

For figlet, I tried both:

import figlet from 'figlet';
import * as figlet from 'figlet';

yet then I get:

 bin/console.ts(1,20): error TS2307: Cannot find module 'figlet'.

How am I suppose to import these libraries?

Fertilization answered 28/11, 2016 at 9:39 Comment(0)
P
5

The key is that TypeScript has to be able to find the module you're referring to, so it can type check your usage of it. It's hard to know how exactly to do that in your project without more information, but generally the answer is to install type definitions for the JavaScript libraries you're interested in.

The easiest way to do this if you have no existing infrastructure is usually npm. For aws-sdk for example, if you run npm install --save @types/aws-sdk then the type definitions will be downloaded to node_modules/@types/aws-sdk inside your project, and the TypeScript compiler will automatically find them there, so if you import aws-sdk it'll know what's going on.

The same will work for commander too. Figlet though doesn't seem to have any published declaration files, so you'll have to put together your own. You can either actually describing the types, or explicitly giving the module the any type:

  • Describing the types is more complicated, but a good way to understand how this all works. Try reading the type declarations section in the handbook. Taking a look at other existing type definitions (most of them are in the DefinitelyTyped repo) is another good way to get to grips with this.

  • Explicitly giving it the any type and ignoring the issue will be much easier, but you won't get any type system support when using figlet. There's a shorthand for exactly this though: create a figlet.d.ts file in your project, and in it just put declare module "figlet";. This is a shorthand ambient module and should be enough to let you import figlet successfully.

Take a look at consuming declaration files and module resolution generally in the handbook for more details.

Pigment answered 28/11, 2016 at 10:58 Comment(0)
F
10

Tim answer is perfect, the error is because for importing something typescript need its type definitions (property "typings" in target package.json pointing to a .d.ts file with module's descriptions.

Also you could try this: import figlet = require('figlet') and in tsconfig.json compilerOptions.esModuleInterop === true

Regarding the equivalence, this heped me to start:

  • import * as foo from 'foo'; is equivalent to const foo = require('foo') (foo is doing module.exports = foo)
  • import {bar} from 'foo' is equivalent to const bar = require('foo').bar (foo is doing module.exports = {bar}

hope it helps

Foveola answered 16/6, 2018 at 19:0 Comment(0)
P
5

The key is that TypeScript has to be able to find the module you're referring to, so it can type check your usage of it. It's hard to know how exactly to do that in your project without more information, but generally the answer is to install type definitions for the JavaScript libraries you're interested in.

The easiest way to do this if you have no existing infrastructure is usually npm. For aws-sdk for example, if you run npm install --save @types/aws-sdk then the type definitions will be downloaded to node_modules/@types/aws-sdk inside your project, and the TypeScript compiler will automatically find them there, so if you import aws-sdk it'll know what's going on.

The same will work for commander too. Figlet though doesn't seem to have any published declaration files, so you'll have to put together your own. You can either actually describing the types, or explicitly giving the module the any type:

  • Describing the types is more complicated, but a good way to understand how this all works. Try reading the type declarations section in the handbook. Taking a look at other existing type definitions (most of them are in the DefinitelyTyped repo) is another good way to get to grips with this.

  • Explicitly giving it the any type and ignoring the issue will be much easier, but you won't get any type system support when using figlet. There's a shorthand for exactly this though: create a figlet.d.ts file in your project, and in it just put declare module "figlet";. This is a shorthand ambient module and should be enough to let you import figlet successfully.

Take a look at consuming declaration files and module resolution generally in the handbook for more details.

Pigment answered 28/11, 2016 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.