TypeScript 模块与全局声

关键知识点:d.ts 文件中的模块化与全局声明

问题描述

当在 .d.ts 文件中添加 importexport 语句时,该文件会被 TypeScript 视为模块(module),而不是全局脚本文件。这会导致文件中的声明仅在模块内部可见,而不是全局可见。

// 这会使文件变成模块,声明不再是全局的
import { Api } from './types';

declare var api: Api; // 这个声明只在模块内可见

解决方案

在模块文件中声明全局变量,需要使用 declare global {} 块:

// 使用 import type 只导入类型,不影响运行时
import type { Api } from './types';

declare global {
  var api: Api; // 这个声明会添加到全局作用域
}

TypeScript 模块规则总结

  1. 模块识别规则

    • 包含顶级 importexport 语句的文件被视为模块
    • 不包含这些语句的文件被视为全局脚本
  2. 声明作用域

    • 在全局脚本中,declare 声明的类型/变量自动添加到全局作用域
    • 在模块中,declare 声明的类型/变量仅在该模块内可见
  3. 在模块中添加全局声明

    • 使用 declare global { ... }
    • 这允许模块文件向全局命名空间添加类型
  4. 类型导入优化

    • 使用 import type 而不是 import 可以确保只导入类型信息
    • 这不会影响运行时行为,也不会导致额外的 JavaScript 代码生成

实际应用

这种模式在前端项目中特别有用,例如在全局注入 API 客户端时:

  1. .d.ts 文件中声明全局类型
  2. 在运行时代码中将实际对象赋值给全局变量(如 window.api = api
  3. 在整个应用程序中可以直接使用全局变量,同时获得完整的类型支持

这种方式既保持了类型安全,又提供了便捷的全局访问。

posted @ 2025-07-11 12:49  丁少华  阅读(14)  评论(0)    收藏  举报