使用第三方JavaScript

在使用 npm 命令安装第三方库时,可能会出现以下几种情况。

  • 第三方 JavaScript 库自带声明文件。

  • 第三方 JavaScript 库没有自带声明文件,但 DefinitelyTyped 仓库中具有声明文件。

  • 完全没有声明文件,需要自行编写声明模块。

对于这 3 种情况,处理方式各不相同。本节分别进行介绍。

使用自带声明文件的第三方库

自带声明文件的第三方库通常是直接由 TypeScript 版本编译为 JavaScript 版本的,也有少部分是发布者后添加的。这种库文件安装后就可以直接使用代码补全、接口提示、类型检查等功能,无须做任何处理。

例如,Redis 库是一个轻量级的、可连接 Redis 数据库的库文件。先执行以下命令,安装 redis 库。

$ npm install redis

由于 Redis 库自带声明文件,因此使用时不会引起任何编译错误,且能够进行代码补全和提示。图21-3所示为 IDE 智能提示。

image 2024 02 20 12 27 21 422
Figure 1. 图21-3 IDE智能提示

查看项目结构下的 \node_modules\redis\dist,可以看到 Redis 库的 JavaScript 库文件及其声明文件。在本例中,项目结构如下。

D:\TSProject\node_modules\redis\dist
    index.d.ts
    index.js

使用DefinitelyTyped声明文件库

DefinitelyTyped 是一个开源的、高质量的 TypeScript 声明文件库,其中几乎涵盖了所有主流 JavaScript 库的声明文件。如果第三方 JavaScript 库没有自带声明文件,可以查看 DefinitelyTyped 库中是否具有声明文件。

声明文件的安装命令如下。

$ npm install @types/库名称

例如,jQuery 库并没有自带声明文件,虽然使用 npm install jquery 命令可以成功安装 jQuery 库,但由于没有声明文件,因此直接使用将会出现图21-4所示的错误。

image 2024 02 20 12 29 25 414
Figure 2. 图21-4 导入模块时的编译错误

此时,执行以下代码,从 DefinitelyTyped 库中安装 jQuery 库的声明文件来解决此问题。

$ npm install @types/jquery

虽然 DefinitelyTyped 仓库中维护了各个主流第三方库的声明文件,但由于它是由开源社区维护的,因此难免有不完整或更新不及时的情况。如果遇到这种情况,需要手动更改声明文件。

自行编写声明模块

对于某些第三方库,如果它没有声明文件,而且 DefinitelyTyped 仓库中也没有其对应的声明文件,但 TypeScript 项目中需要用到该库的功能,就可以自行编写声明模块。

21.1.2 节提到了不同的声明形式,其中 declare module 用于声明模块。此功能仅用于非相对模块名称(关于非相对模块,详见13.1.6节),因此声明模块通常只用于使用第三方库的情况。

例如,以下代码中声明了一个名为 moduleA 的模块,并在其中导出了部分声明。

declare module 'moduleA' {
    export let variable1: string;
    export function sum(a: number, b: number): number;
    let object1: { name: string, print: () => void }
    export default object1;
}

之后,你可以在 TypeScript 中使用此模块。

import { sum, variable1, default as module1 } from 'moduleA'

在前面的示例中,使用了 request 框架(执行命令 npm install request 安装)来返回百度页面的 HTML,代码如下。

import request from 'request'

request('http://www.baidu.com', function (error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body) //显示百度首页的HTML源码
    }
})

如果开启了严格模式(设置 "strict": true),则会出现图21-5所示的编译错误。

image 2024 02 20 12 33 58 757
Figure 3. 图21-5 严格模式下的编译错误

通过声明模块解决这个问题,例如,创建一个名为 request.d.ts 的声明文件,其内容如下。

declare module 'request' {
    export default function request(
        url: string,
        callback: (error: string, response: { statusCode: number }, body: string)
        => void
    ): void;
}

之后就不会再出现编译错误,而且能够使用代码补全、接口提示、类型检查等功能。

使用以下代码声明一个类型为 any 的模块,这样模块中的所有声明都会被当作 any 类型而忽略类型检查。虽然使用这种方法可以编译通过,但是在实际项目中并不推荐这种方法。

declare module 'request'