You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript无法识别typeRoots配置目录下的全局自定义类型(如User)

TypeScript无法识别typeRoots配置目录下的全局自定义类型(如User)

看起来你踩了TypeScript typeRoots 配置的两个常见误区,我来帮你拆解问题并给出可行的解决办法:

问题根源分析

1. typeRoots 的作用被误解

typeRoots 并不是用来自动加载任意目录下的模块类型的——它的设计目标是指定全局类型声明文件(没有export/import的.d.ts)或者**@types风格的类型包目录**(每个类型是一个子目录,比如@types/react这种结构)。

你的types.d.ts里用了export type User = ...,这会让文件变成一个模块,而不是全局类型声明。这种情况下,不管typeRoots怎么配置,TypeScript都不会自动把模块里的类型变成全局可用的。

2. 即使目录被扫描,模块类型也不会自动导入

从你的--traceResolution输出能看到TS确实在检查src/generated目录,但因为这个文件是模块,TS不会主动导入它的内容——你必须手动导入,或者把它改成全局声明。

可行的解决方案

方案1:手动导入类型(最推荐,符合模块规范)

既然types.d.ts是模块,直接在需要用User的文件里手动导入即可:

// src/util/userUtil.ts
import type { User } from '../generated/types';

export const getUser = (id: string): User => {
  // 你的代码逻辑
};

这种方式最清晰,也符合TypeScript的模块设计理念,不需要依赖typeRoots的配置。

方案2:将类型改为全局可用(适合确实需要全局的场景)

如果你希望User等类型不需要导入就能全局使用,可以修改src/generated/types.d.ts,把类型放到全局命名空间中:

// src/generated/types.d.ts
declare global {
  type User = Node & { /* 你的类型定义内容 */ };
  // 其他需要全局的类型也放在这里
}

// 必须加这一行,确保文件被识别为模块,让`declare global`生效
export {};

然后确保tsconfig.json的include包含了这个文件(你说已经包含了,所以没问题),之后User类型就会全局可用,不需要导入。

方案3:调整目录结构适配typeRoots(不推荐,繁琐)

如果你一定要用typeRoots来加载类型,需要把目录改成TS期望的@types风格结构:

  1. 新建目录:src/generated/@types/my-graphql-types
  2. 把types.d.ts的内容移到这个目录下的index.d.ts(注意去掉export,变成全局类型)
  3. 修改tsconfig.json的typeRoots:
    "typeRoots": ["./src/generated/@types", "./node_modules/@types"]
    

这种方式比较繁琐,除非你有大量全局类型包需要管理,否则不推荐使用。

最后再确认下:你的skipLibCheck和include配置没问题,核心问题就是typeRoots的使用场景和模块类型的加载逻辑不匹配,选上面任意一个方案都能解决你的报错。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:13:09