如何从 typescript 使用 npm 模块?

Posted

技术标签:

【中文标题】如何从 typescript 使用 npm 模块?【英文标题】:How to consume npm modules from typescript? 【发布时间】:2016-11-08 12:26:31 【问题描述】:

我正在试一试打字稿。它在 hello world 阶段运行良好。我现在正在尝试使用 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 问题要么没有答案(here 和 here),要么不相关。

元素:

typescript 1.8 最新版 是的,lodash 已安装 npm i --save lodash 并存在于我的文件系统中(已选中) 我也做过typings i --save lodash 变体 import * as _ from 'lodash'const _ = require('lodash') 也不起作用 我尝试按照其他答案 "moduleResolution": "node""module": "commonjs" 中的建议调整 tsconfig.json 选项,如某些答案中的建议,仍然不起作用

我们如何在 typescript 中使用 npm 包??

【问题讨论】:

您是否在 index.ts 中添加了对 lodash.d.ts 的引用?它应该类似于:///<reference path="../typings/lodash/lodash.d.ts"/> @Granga 它有效。您可以将此添加为答案吗? 很高兴它有效。 Blackus 已经添加了答案,它指定了我更好的建议。不过需要注意的是:当在命令行上指定输入文件时(这是您的情况),tsconfig.json 文件将被忽略。 (source) 【参考方案1】:

[编辑] 非常感谢您的回答!但是,截至 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 文件上编写自己的代码,或者忽略库的类型检查。

要完全忽略类型检查(这不是推荐的方式),请在 any 类型的变量上导入库。

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

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

tsc 会抱怨require 不存在。提供node 输入或declare 以丢弃错误。

【讨论】:

用 3 个解决方案完成答案。 +1 补充:只要在tsconfig.json 中引用了类型索引,它甚至可以与ts-node 一起使用 我对“声明它以丢弃错误”的意思感到困惑。我是否需要在我尝试导入的模块中进行此更改? 这个答案已经严重过时了。在***.com/a/53786892/587407下方查看我的新答案@【参考方案2】:

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

长话短说,TypeScript 需要关于您的包代码(又名“type declaration files”又名“打字”)的类型信息,并且正确地告诉您,否则您将失去 TypeScript 的全部意义。有几种解决方案可以提供或选择退出,此处按最佳实践顺序列出:


解决方案 0:模块已经提供了类型。如果它的 package.json 包含这样的一行:

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

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


解决方案 1:使用来自 DefinitelyTyped 的社区贡献类型。对于模块“foo”,试试这个:

npm add -D @types/foo

如果它有效,大奖!您现在有了类型并且可以使用您的模块。如果 npm 抱怨找不到模块 @types/foo,让我们继续...


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

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

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

您也可以尝试自己编写类型信息,查看official doc 和/或DefinitelyTyped 中的示例。如果这样做,请考虑将您的类型直接贡献到模块中(解决方案 0,如果模块作者接受)或肯定类型(解决方案 1)

【讨论】:

@Offirmo,我们也可以在一个文件中声明多个自定义类型!所以,不需要多个文件(也许?)。 第 2 步。Reference the content of this folder in your tsconfig.json: 给出以下错误:Unknown compiler option 'include'. @Sumit 这不是编译器选项,它应该是compilerOptions的兄弟 当我添加包含行时,TS 不再识别 React 本身。 This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. 除了我的 TSConfig 中有 ` "esModuleInterop": true` 【参考方案3】:

您可能错过了Declaration Files。

请参阅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 好点。在这种情况下使用import _ from 'lodash'; 会更好。我已经更新了我的答案,以展示不同的导入方式以及您使用它们的原因。 如果模块没有默认导出,则需要* as _ 。 tsc 编译器会对此发出警告。 “无默认导出”是否意味着没有定义 Typescript 类型(即导入纯 javascript 模块)?我是 JS/Typescript 的新手...... @BigRich "无默认导出" 表示模块没有 export default &lt;...&gt; 语句。查看Typescript Modules Documentation 的“默认导出”部分。【参考方案4】:

它对我有用。

    创建一个名为“typings”的文件夹。

    在typings文件夹中,创建一个文件名module-name.d.ts。它包含:

    declare module "module-name";

    在tsconfig.json中,参考文件夹

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

【讨论】:

嗨!感谢您的贡献。此方法已包含在我的答案中,只能作为最后的手段使用。 第 3 步:In tsconfig.json, refer to the folder,出现以下错误:Unknown compiler option 'typesRoots'. @Sumit 在我的例子中,“typesRoots”在“compilerOptions”中 是 typeRoots 而不是 typesRoots,应该在 compilerOptions 里面【参考方案5】:

我遇到了这个错误,没有一个答案对我有用,但是当你想在 typescript 中使用节点模块时,我想出了一些办法,将它们安装为

$npm install @types/<module_name>

例如

npm install @types/cheerio

而不是说

npm install cheerio

【讨论】:

这是已接受答案的解决方案 1。

以上是关于如何从 typescript 使用 npm 模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 typescript / gulp / browserify 导入 npm 模块

模块解析:NPM 安装来自 Github 的 Typescript 包

如何在 TypeScript npm 模块中导出类型

如何在 Visual Studio 2019 中使用具有功能的 .net core + typescript + webpack + npm 模块?

NPM 模块 + TypeScript 最佳实践

如何将 typescript npm 模块导入语法转换为 ECMA2015 模块导入语法