如何配置TypeScript以识别@testing-library/jest-dom的类型?
问题
如何配置TypeScript,使其找到@testing-library/jest-dom的类型定义?
当前tsconfig配置
{ "compilerOptions": { "noEmit": true, "allowJs": true, "esModuleInterop": true, "target": "esnext", "module": "esnext", "moduleResolution": "node", "baseUrl": "./", "skipLibCheck": false, "rootDirs": [ "./src", "../.redwood/types/mirror/web/src", "../api/src", "../.redwood/types/mirror/api/src" ], "paths": { "src/*": [ "./src/*", "../.redwood/types/mirror/web/src/*", "../api/src/*", "../.redwood/types/mirror/api/src/*" ], "$api/*": [ "../api/*" ], "types/*": ["./types/*", "../types/*"], "@redwoodjs/testing": ["../node_modules/@redwoodjs/testing/web"] }, "typeRoots": ["../node_modules/@types", "./node_modules/@types"], "types": ["jest", "@testing-library/jest-dom"], "jsx": "preserve" }, "include": [ "src", "../.redwood/types/includes/all-*", "../.redwood/types/includes/web-*", "../types", "./types" ] }
运行命令后的错误
执行tsc --noEmit --skipLibCheck时出现以下错误:
error TS2688: Cannot find type definition file for '@testing-library/jest-dom'. The file is in the program because: Entry point of type library '@testing-library/jest-dom' specified in compilerOptions tsconfig.json:29:23 29 "types": ["jest", "@testing-library/jest-dom"], ~~~~~~~~~~~~~~~~~~~~~~~~~~~ File is entry point of type library specified here. Found 1 error.
package.json配置
{ "name": "web", "version": "0.0.0", "private": true, "browserslist": { "development": [ "last 1 version" ], "production": [ "defaults" ] }, "dependencies": { "@redwoodjs/auth-dbauth-web": "7.0.0-canary.711", "@redwoodjs/forms": "7.0.0-canary.711", "@redwoodjs/router": "7.0.0-canary.711", "@redwoodjs/web": "7.0.0-canary.711", "humanize-string": "2.1.0", "react": "0.0.0-experimental-e5205658f-20230913", "react-dom": "0.0.0-experimental-e5205658f-20230913" }, "devDependencies": { "@redwoodjs/vite": "7.0.0-canary.711", "@testing-library/jest-dom": "^6.1.5", "@types/react": "18.2.37", "@types/react-dom": "18.2.15", "autoprefixer": "^10.4.16", "postcss": "^8.4.32", "postcss-loader": "^7.3.3", "prettier-plugin-tailwindcss": "0.4.1", "tailwindcss": "^3.3.6" } }
补充细节
该配置在@testing-library/jest-dom v5版本时正常工作,但升级到v6后出现问题。如果从tsconfig的types数组中移除它,会出现属性缺失的类型错误;目前可通过在测试文件中添加import '@testing-library/jest-dom'临时解决,但想了解为何现在需要这么做。
解决方案与原因分析
问题根源:v6版本的类型定义结构变更
@testing-library/jest-dom v6做了核心调整:
- v5版本的类型定义放在独立的
@types/testing-library__jest-dom包中,TypeScript可以通过typeRoots配置(指向node_modules/@types)自动找到这些类型文件,所以在types数组中配置就能全局生效。 - v6版本开始,类型定义直接内置在
@testing-library/jest-dom包本身,不再依赖单独的@types包。但TypeScript的types配置项只会去typeRoots指定的目录查找类型入口,无法识别包内内置的类型定义,因此抛出找不到类型文件的错误。
正确配置方式
方式1:移除types中的配置,依赖TypeScript自动扫描
TypeScript默认会自动读取node_modules中所有包的package.json里的types字段,加载内置类型。只需:
- 从
compilerOptions.types数组中删除"@testing-library/jest-dom" - 确保
include配置覆盖所有测试文件,比如补充测试文件路径:
"include": [ // 原有配置 "src/**/*.test.tsx", "src/**/*.spec.tsx" ]
方式2:保留types配置,添加路径映射
如果一定要维持types数组的配置,可以通过paths手动指定类型文件路径:
"paths": { // 原有配置 "@testing-library/jest-dom": ["../node_modules/@testing-library/jest-dom/types/index.d.ts"] }
方式3:全局导入类型(优化临时方案)
不想在每个测试文件单独导入的话,可以在项目根目录创建types/jest-dom.d.ts文件,内容为:
import '@testing-library/jest-dom';
你的tsconfig已经包含了"./types"在include中,TypeScript会自动加载这个文件,全局生效类型定义。
为什么手动导入能解决问题?
当你在测试文件中执行import '@testing-library/jest-dom'时,TypeScript会加载该模块的同时,读取包内内置的类型定义文件,从而识别toBeInTheDocument等扩展匹配器的类型。而v5版本不需要这么做,是因为类型文件在@types目录下,符合types配置项的查找逻辑。
内容的提问来源于stack exchange,提问作者Tobbe
相关产品推荐
相关产品推荐

