如何将require 转化为第三方库的import 语句?

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

在我的打字稿项目中,我使用:

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

我想重构这些行以通过 import 工作,以遵守 tslint 的 no-var-requires 规则。然而它的工作方式却让我摸不着头脑。

对于figlet,我都试过了:

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

然后我得到:

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

我应该如何导入这些库?

关键是 TypeScript 必须能够找到您所指的模块,这样它才能对您的使用情况进行类型检查。如果没有更多信息,很难知道在您的项目中究竟如何做到这一点,但通常答案是为您感兴趣的 JavaScript 库安装类型定义。

如果您没有现有的基础架构,最简单的方法通常是 npm。例如,对于 aws-sdk,如果你 运行 npm install --save @types/aws-sdk 那么类型定义将被下载到你项目中的 node_modules/@types/aws-sdk,并且 TypeScript 编译器会自动在那里找到它们,所以如果你导入aws-sdk 它会知道发生了什么。

同样适用于指挥官。尽管 Figlet 似乎没有任何已发布的声明文件,因此您必须将自己的声明文件放在一起。您可以实际描述类型,或者显式地为模块提供 any 类型:

  • 描述类型比较复杂,但这是了解这一切如何工作的好方法。尝试阅读 type declarations section in the handbook. Taking a look at other existing type definitions (most of them are in the DefinitelyTyped 存储库)是掌握这一点的另一种好方法。

  • 明确地给它 any 类型并忽略这个问题会容易得多,但是使用 figlet 时你不会得到任何类型系统支持。不过有一个 shorthand 就是为了这个:在您的项目中创建一个 figlet.d.ts 文件,然后在其中放入 declare module "figlet";。这是一个 shorthand ambient module,应该足以让您成功导入 figlet。

查看手册中的 consuming declaration files and module resolution generally 了解更多详情。

Tim 的回答很完美,错误是因为要导入某些东西,打字稿需要其类型定义(目标 package.json 中的 属性 "typings" 指向 .d.ts 文件与模块的描述。

你也可以试试这个:import figlet = require('figlet') 和 tsconfig.json compilerOptions.esModuleInterop === true

关于等价性,这让我开始:

  • import * as foo from 'foo';等同于const foo = require('foo')(foo在做module.exports = foo
  • import {bar} from 'foo' 等同于 const bar = require('foo').bar (foo 正在做 module.exports = {bar}

希望对您有所帮助