如何使用打字稿中的npm模块?


88

我正在尝试打字稿。在hello世界阶段它工作正常。我现在正在尝试使用npm模块:

index.ts =

import _ = require('lodash')

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

这不起作用:

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

查看打字稿文档和谷歌没有帮助。其他S / O问题未得到回答(此处此处)或无关。

元素:

  • 打字稿1.8最新
  • 是的,lodash已安装npm i --save lodash并存在于我的文件系统中(已选中)
  • 我也做了 typings i --save lodash
  • 变种import * as _ from 'lodash'const _ = require('lodash')不起作用
  • 我试图调整tsconfig.json选择在其他的答案建议 "moduleResolution": "node",并"module": "commonjs"在一些答案建议,仍然无法正常工作

我们如何在打字稿中使用npm包?


2
您是否在index.ts中添加了对lodash.d.ts的引用?它看起来应该类似于: ///<reference path="../typings/lodash/lodash.d.ts"/>
Granga

@Granga有效。您可以将此添加为答案吗?
Offirmo

2
很高兴它有效。Blackus已经添加了答案,它指明了我的建议甚至更好。不过请注意:在命令行上指定输入文件时(这是您的情况),tsconfig.json文件将被忽略。来源
Granga

Answers:


61

[EDIT]非常感谢您的回答!但是,截至2018年,它已过时。读者,请看一下其他答案。

有几种从npm导入模块的方法。但是,如果您没有输入内容tsc,那么总会抱怨它找不到您需要的模块(即使已编译的js确实在工作)。

  • 如果您确实有键入内容,并且不使用tsconfig.json,请使用reference来导入键入内容:

    /// <reference path="path/to/typings/typings.d.ts" />
    
    import * as _ from 'lodash`;
    
    console.log(_.toUpper('Hello, world !'))
    
  • 如果您使用的是tsconfig.json文件,请确保包括(或不排除)您的键入文件,并在import上一个示例中进行类似操作。

如果没有可用的类型。您有两种选择:在.d.ts文件上编写自己的文件,或忽略库的类型检查。

要完全忽略类型检查(不建议这样做),请在type变量上导入库any

 const _: any = require('lodash');

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

tsc会抱怨require说不存在。提供类型node,否则declare将其丢弃。


2
使用3种解决方案来完成答案。+1
Offirmo '16

另外:它甚至工作ts-node,只要分型指数中引用tsconfig.json
Offirmo

我对“声明放弃错误”的意思感到困惑。我需要在要导入的模块中进行此更改吗?
子弹

1
这个答案已经严重过时了。在下面查看我的新答案stackoverflow.com/a/53786892/587407
Offirmo

50

[2018/12]这是我在2016年提出的最新,最新答案,尽管答案过时,但仍然显示出很多活动。

长话短说,TypeScript需要有关程序包代码的类型信息(又称“类型声明文件”或“ typings”),并正确地告诉您,否则您将失去TypeScript的全部内容。按照最佳实践的顺序,列出了提供或选择退出的几种解决方案:


解决方案0:该模块已经提供了类型。如果其package.json包含以下行:

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

它已经启用了TypeScript。如果您正在阅读此页面,则很可能不是这种情况,所以让我们继续...


解决方案1:使用来自DefinitelyTyped的社区贡献的类型。对于模块“ foo”,请尝试以下操作:

npm add -D @types/foo

如果有效,请中奖!现在,您可以进行输入并可以使用您的模块了。如果npm抱怨找不到模块@ types / foo,让我们继续...


解决方案2:提供有关此模块的自定义类型。(可以选择零努力)

  1. 在项目的根目录下创建一个名为“ typings-custom”的文件夹
  2. 在tsconfig.json中引用此文件夹的内容:
"include": [
    "./typings-custom/**/*.ts"
]
  1. 创建一个具有以下确切名称的文件:foo.d.ts [foo =模块名称],内容如下:
declare module 'foo'

您的TypeScript代码现在应该编译,尽管没有类型信息(TypeScript考虑类型为“ any”的foo模块)。

您也可以尝试自己编写类型信息,查看官方文档和/或DefinitelyTyped中的示例。如果您这样做了,可以考虑将您的类型直接贡献给模块(如果模块作者接受,则为解决方案0),或者直接贡献给DefinitelyTyped(解决方案1)


1
@Offirmo,我们也可以在一个文件中声明多个自定义类型!因此,不需要多个文件(也许吗?)。
lazycipher

步骤2Reference the content of this folder in your tsconfig.json:出现以下错误: Unknown compiler option 'include'.
Sumit

1
@Sumit它不是编译器选项,应该是compilerOptions
1980年

22

您可能会缺少宣言文件

有关更多信息,请参见DefinitelyTyped


试试这个:

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

现在可以导入了。

import _ from 'lodash';

如果您要导入的模块具有多个导出,则可以执行以下操作:

import { Express, Router } from 'express';

如果要导入的模块“没有默认导出”,则需要执行以下操作:

import * as http from 'http';

为什么我们必须使用* as _而不仅仅是_ from 'lodash'ES6代码?
JohnnyQ '17

@JohnnyQ好点。import _ from 'lodash';在这种情况下,使用效果更好。我已经更新了答案,以显示不同的导入方式以及为什么要使用它们。
Derek Soike

1
* as _ 如果模块没有默认导出,则需要。tsc编译器将对此发出警告。
user2867342 '17

“没有默认导出”是否意味着没有定义Typescript类型(即,导入纯JavaScript模块)?我是新来的JS /打字稿....
大富

2
@BigRich“无默认导出”表示该模块没有export default <...>语句。查看Typescript模块文档的“默认导出”部分。
德里克·索克

4

它为我工作。

  1. 创建一个名为“ typings”的文件夹。
  2. 在类型文件夹中,创建一个文件名module-name.d.ts。它包含了:

    declare module "module-name";

  3. 在tsconfig.json中,引用文件夹

    "typeRoots": [ "./typings", "../node_modules/@types" ]


嗨!感谢您的贡献。这种方法已经包含在我的答案中,应仅用作最后的手段。
Offirmo

步骤3:In tsconfig.json, refer to the folder给出以下错误:Unknown compiler option 'typesRoots'.
Sumit Sumit

1
@Sumit在我的案例中,“ typesRoots”位于“ compilerOptions”内部
Quynh Ngo,

1
它是typeRoots而不是typesRoots,应该在CompilerOptions内部
CM

0

我一直收到此错误,没有答案对我有用,但是当您想在打字稿中使用节点模块时,我想出了一些办法将它们安装为

$npm install @types/<module_name>

例如

npm install @types/cheerio

而不是说

npm install cheerio
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.