简体中文
  • typescript
  • javascript
  • nodejs
  • node_modules
  • module-augmentation

TypeScript 模块的增强和处理嵌套的 JavaScript 文件

学习 TypeScript 中的模块增强基础知识,以及如何为嵌套的 JavaScript 文件添加类型定义。

Gao
Gao
Founder

不要在用户认证上浪费数周时间
使用 Logto 更快地发布安全应用。几分钟内集成用户认证,专注于您的核心产品。
立即开始
Product screenshot

TypeScript 已成为 JavaScript 生态系统中非常宝贵的补充,超过十年来因其能够为 JavaScript 代码提供类型安全而备受欢迎。

JavaScript 包的类型

为了向后兼容性和灵活性,TypeScript 允许包作者为他们的 JavaScript 包提供类型定义。这些类型定义通常存储在 "DefinitelyTyped" 仓库中。你可以使用 @types 作用域来安装这些类型定义,例如,@types/react 是 React 包的类型定义。

安装这些类型定义之后,你可以自信地使用该包,并确保类型安全性。以下是使用类型安全性定义 React 组件的示例:

模块增强

虽然大多数流行的 JavaScript 包在 @types 作用域中已有现成的类型定义,有些包可能缺少类型定义或类型定义已过时。在这种情况下,TypeScript 提供了一个强大的功能,称为 "模块增强",用于为这些包添加类型定义。我们来看一个示例:

现在你可以在代码中使用这个增强的类型定义了:

模块增强不仅允许你为包添加类型定义,还可以扩展现有的类型定义。例如,你可以为 window 对象添加一个新属性:

并在代码中使用它:

之前的文章 中,我们讨论了 React Router 库中的一个类型问题,并且通过扩展和增强现有类型在自定义声明文件中克服了这个影响。

请记住,在使用模块增强时,通过仔细检查 JavaScript 源代码,以确保类型定义的准确性至关重要。不正确的类型定义可能会导致运行时错误。在上述示例中,window.foo 属性必须是存在于 window 对象上的一个字符串。

全局增强

有时你可能会遇到引入全局变量的脚本,你可能希望为这些全局变量提供类型定义,以便在 TypeScript 代码中使用它们。例如,如果你有一个设置了名为 __DEV__ 的全局变量的脚本:

你可以为这个全局变量添加类型定义,如下所示:

现在你可以在 TypeScript 代码中使用它了:

通过结合模块增强和全局增强,你甚至可以扩展 JavaScript 原型的类型定义。然而,通常不推荐这样做,因为它可能会污染全局作用域。

模块增强的强大功能允许进行这种扩展,但需要谨慎操作,以防止污染全局作用域。

嵌套的 JavaScript 文件

在前面提到的示例中,我们假设导入可以通过包的入口文件解析。然而,有些包会导出没有相应类型定义的嵌套 JavaScript 文件。考虑一个名为 foo 的包,它具有以下结构:

foo 包导出 index.js 文件作为入口点,并且还导出 bar 目录。

要增强 foo 包的类型定义,你可以创建一个 foo.d.ts 文件:

然而,如果你尝试在 TypeScript 中导入 baz.js 文件,将会遇到错误:

为了增强 baz.js 文件的类型定义,你需要创建一个单独的 baz.d.ts 文件:

这可以确保 TypeScript 能够定位模块及其关联的类型定义:

为了保持类型定义的有序性,你可以在类型定义文件中模仿包的结构:

这种方法使你的 TypeScript 代码保持结构化并且类型安全,即使是在处理嵌套的 JavaScript 文件时。