TypeScript4配置typeRoots扩展全局接口不生效问题
TypeScript 3升级至4后扩展Array全局接口属性不存在问题修复
配置存在的核心错误
TS4收紧了全局类型声明校验、模块识别、类型合并的相关规则,TS3下可运行的不规范写法在TS4中会直接失效,当前配置和代码存在4个核心问题:
- 路径不匹配:类型声明文件实际存放在
src/@types/array.d.ts,但tsconfig中typeRoots配置的是项目根目录下的@types文件夹,include配置的"@types/*"也指向根目录@types,路径不一致导致类型扫描逻辑无法正确索引到声明文件。 - 声明写法不符合TS4模块规则:当前array.d.ts内使用了
declare global包裹扩展逻辑,但文件顶层没有任何import/export语句,TS会将其识别为普通脚本而非ES模块,TS4不再对普通脚本内的declare global块执行全局类型合并。 - 泛型声明不规范:全局Array本身是泛型接口,原声明中直接定义
interface Array未携带泛型参数,TS4下无法和内置的Array泛型类型正确合并。 - typeRoots机制认知错误:typeRoots默认只会加载配置路径下的子文件夹作为独立类型包,直接散放在typeRoots目录根下的.d.ts文件不会被自动加载,冗余配置反而干扰了正常的类型扫描逻辑。
修复步骤
按以下顺序调整即可解决问题:
- 修正类型声明文件写法,二选一即可:
写法1(直接全局声明,无需declare global):
写法2(保留declare global,显式标记为模块):// src/@types/array.d.ts interface Array<T> { /** * @example [["key", "value"]]._toH() -> * { key: "value" } */ _toH(): object /** returns the last element of the array */ _last(): any }// src/@types/array.d.ts declare global { interface Array<T> { _toH(): object _last(): any } } // 必须加这一行,将文件标记为ES模块,declare global才会生效 export {} - 调整tsconfig配置,去掉冗余的typeRoots配置即可(因为include已经配置了
"src/**/*",src下所有.d.ts文件都会被自动识别,不需要额外配置typeRoots),调整后的tsconfig关键配置如下:
如果需要保留自定义typeRoots配置,把路径修正为实际存放声明文件的{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": ["src/**/*", "scripts/**/*", ".eslintrc.js"] }src/@types即可,同时同步修改include中的对应路径。 - 配置修改完成后,重启TS服务(编辑器中可通过命令面板触发「TypeScript: Restart TS Server」)清除类型缓存即可生效。
内容的提问来源于stack exchange,提问作者goldylucks
相关产品推荐
相关产品推荐

