Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consume npm modules from typescript?

I'm giving a shot at typescript. It works fine at the hello world stage. I'm now trying to use a npm module :

index.ts =

import _ = require('lodash')

console.log(_.toUpper('Hello, world !'))

This doesn't work :

  • tsc index.ts -> Cannot find module 'lodash'. (2307)
  • node-ts index.js -> Cannot find module 'lodash'. (2307)

Looking at typescript documentation and in google didn't help. Other S/O questions are either unanswered (here and here) or unrelated.

Elements :

  • typescript 1.8 latest
  • Yes, lodash is installed npm i --save lodash and exists in my filesystem (checked)
  • I also did typings i --save lodash
  • variants import * as _ from 'lodash' or const _ = require('lodash') don't work either
  • I tried tweaking tsconfig.json options as suggested in other answers "moduleResolution": "node" and "module": "commonjs" as suggested in some answers, still doesn't work

How do we consume a npm package in typescript ??

like image 928
Offirmo Avatar asked Jul 06 '16 12:07

Offirmo


People also ask

Can you use npm packages in TypeScript?

Globally Installing TypeScript:You can use npm to install TypeScript globally, this means you can use the tsc command anywhere in your terminal. You can also use use npx when you have to run tsc.

How do I use TypeScript modules?

A module can be created using the keyword export and a module can be used in another module using the keyword import . In TypeScript, files containing a top-level export or import are considered modules. For example, we can make the above files as modules as below. console.

Can I use module exports in TypeScript?

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).


3 Answers

[2018/12] New, up-to-date, answer to this question I asked in 2016, which stills shows a lot of activity despite having outdated answers.

Long story short, TypeScript requires type informations about your package's code (a.k.a. "type declaration files" a.k.a. "typings") and rightfully tells you that you would otherwise be losing the whole point of TypeScript. There are several solutions to provide them or opt out of them, listed here in order of best practice:


Solution 0: the module already provides the typings. If its package.json contains a line like this:

"typings": "dist/index.d.ts", 

it is already TypeScript-enabled. It's most likely not the case if you are reading this page, so let's continue...


Solution 1: use community-contributed typings from DefinitelyTyped. For a module "foo", try this:

npm add -D @types/foo 

if it works, jackpot! You now have the typings and can use your module. If npm complains that it can't find the module @types/foo, let's continue...


Solution 2: provide custom typings about this module. (with an option to do zero effort)

  1. Create a folder named "typings-custom" at the root of your project
  2. Reference the content of this folder in your tsconfig.json:
"include": [     "./typings-custom/**/*.ts" ] 
  1. Create a file with this exact name: foo.d.ts [foo = the name of the module] with the content:
declare module 'foo' 

Your TypeScript code should now compile, albeit with NO type information (TypeScript consider the foo module of type "any").

You can also attempt to write the type information yourself, looking at the official doc and/or at examples from DefinitelyTyped. If you do, think of contributing your typings either directly into the module (solution 0, if the module author accepts) or into DefinitelyTyped (solution 1)

like image 142
Offirmo Avatar answered Oct 14 '22 04:10

Offirmo


[EDIT] Thanks a lot for this answer! However, as of 2018, it is outdated. Readers, have a look at the other answers.

There are several ways to import modules from npm. But if you don't get typings, tsc will always complain that it can't find the module you are requiring (even if transpiled js is actually working).

  • If you do have typings and do not use a tsconfig.json, use reference to import the typings:

    /// <reference path="path/to/typings/typings.d.ts" />  import * as _ from 'lodash`;  console.log(_.toUpper('Hello, world !')) 
  • If you are using a tsconfig.json file, be sure to have your typings file included (or not excluded, your choice), and make the import like on the previous example.

In the case when there is no available typings. You have two choices: write your own on a .d.ts file, or ignore type checking for the library.

To completely ignore the type checking (this is no the recommended way), import the library on a variable of type any.

 const _: any = require('lodash');   console.log(_.toUpper('Hello, world !')) 

tsc will complain that require doesn't exist. Provide node typings, or declare it to discard the error.

like image 45
Blackus Avatar answered Oct 14 '22 04:10

Blackus


You're probably missing the Declaration Files.

See DefinitelyTyped for more info.


Try this:

npm install --save lodash
npm install --save @types/lodash

Now you can import.

import _ from 'lodash';

If the module you're importing has multiple exports, you can do this:

import { Express, Router } from 'express';

If the module you're importing "has no default export" you need to do this:

import * as http from 'http';
like image 43
Derek Soike Avatar answered Oct 14 '22 03:10

Derek Soike