如何仅在导入特定模块时声明全局属性类型?
仅在导入特定模块时扩展全局对象类型的解决方案
你遇到的问题是TypeScript中declare global的全局类型扩展会自动合并到所有文件的全局作用域,不管是否导入对应的模块。以下是几种可行的解决方法:
方法1:通过TS配置文件隔离测试环境类型
这是最稳妥的方案,通过拆分TS配置文件,让主项目和测试环境加载不同的类型文件:
- 在项目根目录创建两个配置文件:
- 主项目配置
tsconfig.json:排除测试文件和环境配置模块,避免加载全局类型扩展:{ "compilerOptions": { /* 你的主项目编译配置 */ }, "include": ["src/**/*"], "exclude": ["__tests__/**/*", "env/**/*"] } - 测试环境配置
tsconfig.test.json:继承主配置并包含测试文件和环境模块:{ "extends": "./tsconfig.json", "include": ["__tests__/**/*", "env/**/*"] }
- 主项目配置
- 运行测试时指定使用测试配置(比如
ts-jest可以在jest.config.js中设置tsconfig: './tsconfig.test.json')。
这样主项目编译时不会处理env/index.ts,自然不会加载其中的全局类型,只有测试环境会生效。
方法2:使用引用指令手动引入类型
如果不想拆分配置,可以把全局类型放在单独的.d.ts文件中,仅在需要的测试文件中通过引用指令引入:
- 创建
env/foo.d.ts存放全局类型声明:declare global { var foo: Foo; } export {}; - 在测试文件中同时引入类型和模块代码:
/// <reference path="../env/foo.d.ts" /> import '../env'; foo.fooMethod(); // 类型提示正常
主项目文件中没有这个引用指令,就不会识别foo的类型。
方法3:模块内导出类型并手动扩展全局(繁琐但无需改配置)
如果以上两种方法都不适用,可以在模块中导出类型,然后在每个测试文件中手动扩展全局作用域:
env/index.ts中导出类型并添加全局属性:export type FooType = Foo; // 实际给全局对象添加属性的代码 global.foo = new Foo();- 测试文件中导入类型并扩展全局:
import type { FooType } from '../env'; import '../env'; declare global { var foo: FooType; } foo.fooMethod(); // 类型提示正常
这种方法需要每个测试文件都写全局扩展代码,适合测试文件较少的场景。
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

