React Router编译正常但启动时报类型不兼容错误求助
React Router 类型不兼容错误排查及解决
问题场景
我配置了如下路由:
const router = createBrowserRouter( createRoutesFromElements( <> <Route path="/login" element={<LoginPage />} /> <Route errorElement={<ErrorView />} path="/" element={<Layout />}> <Route path="/stacks" element={<StackList />} /> <Route path="/stacks/:name" element={<StackDetails />} /> <Route path="/instances" element={<InstancesList />} /> <Route path="/new" element={<NewInstance />} /> </Route> </> ) )
执行yarn start时触发类型错误,具体信息如下:
ERROR in src/index.tsx:18:5 TS2345: Argument of type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/dist/lib/context").RouteObject[]' is not assignable to parameter of type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router-dom/node_modules/react-router/dist/lib/context").RouteObject[]'. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/dist/lib/context").RouteObject' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router-dom/node_modules/react-router/dist/lib/context").RouteObject'. Type 'IndexRouteObject' is not assignable to type 'RouteObject'. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/dist/lib/context").IndexRouteObject' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router-dom/node_modules/react-router/dist/lib/context").IndexRouteObject'. Types of property 'shouldRevalidate' are incompatible. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/node_modules/@remix-run/router/dist/utils").ShouldRevalidateFunction' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").ShouldRevalidateFunction'. Types of parameters 'args' and 'args' are incompatible. Type '{ currentUrl: URL; currentParams: import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").Params<string>; nextUrl: URL; nextParams: import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").Params<...>; ... 5 more ...; defaultShouldRevalidate: boolean...' is not assignable to type '{ currentUrl: URL; currentParams: import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/node_modules/@remix-run/router/dist/utils").Params<string>; ... 7 more ...; defaultShouldRevalidate: boolean; }'. Types of property 'actionResult' are incompatible. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").DataResult' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/node_modules/@remix-run/router/dist/utils").DataResult'. Type 'DeferredResult' is not assignable to type 'DataResult'. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").DeferredResult' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/node_modules/@remix-run/router/dist/utils").DeferredResult'. Types of property 'deferredData' are incompatible. Type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/@remix-run/router/dist/utils").DeferredData' is not assignable to type 'import("/home/tons/IdeaProjects/im-web-client/node_modules/react-router/node_modules/@remix-run/router/dist/utils").DeferredData'. Types have separate declarations of a private property 'pendingKeys'. 16 | 17 | const router = createBrowserRouter( > 18 | createRoutesFromElements( | ^^^^^^^^^^^^^^^^^^^^^^^^^ > 19 | <> | ^^^^^^^^^^ > 20 | <Route path="/login" element={<LoginPage />} /> | ^^^^^^^^^^ > 21 | <Route errorElement={<ErrorView />} path="/" element={<Layout />}> | ^^^^^^^^^^ > 22 | <Route path="/stacks" element={<StackList />} /> | ^^^^^^^^^^ > 23 | <Route path="/stacks/:name" element={<StackDetails />} /> | ^^^^^^^^^^ > 24 | <Route path="/instances" element={<InstancesList />} /> | ^^^^^^^^^^ > 25 | <Route path="/new" element={<NewInstance />} /> | ^^^^^^^^^^ > 26 | </Route> | ^^^^^^^^^^ > 27 | </> | ^^^^^^^^^^ > 28 | ) | ^^^^^^ 29 | ) 30 | 31 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
补充依赖配置(package.json)
{ "name": "instance-manager", "version": "0.1.0", "private": true, "dependencies": { "@dhis2/app-runtime": "^3.6.1", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/ui": "^8.6.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", "@types/node": "^16.18.0", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", "@types/react-router-dom": "^5.3.3", "axios": "^1.1.3", "react": "^18.2.0", "react-auth-kit": "^2.6.0", "react-dom": "^18.2.0", "react-router": "^6.4.3", "react-router-dom": "^6.4.2", "react-scripts": "5.0.1", "styled-jsx": "^5.1.0", "typescript": "^4.8.4", "web-vitals": "^2.1.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "format": "yarn d2-style apply" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@dhis2/cli-style": "^10.4.2" } }
问题原因及解决方法
核心原因
react-router(6.4.3)和react-router-dom(6.4.2)版本不匹配,导致二者依赖的@remix-run/router包版本冲突,类型定义无法兼容。- 安装了v5版本的
@types/react-router-dom,但实际使用的是v6版本的路由库,类型定义完全不匹配。
解决步骤
统一路由库版本
修改package.json中react-router和react-router-dom的版本,保持二者一致:"react-router": "^6.4.3", "react-router-dom": "^6.4.3"移除过时的类型依赖
React Router v6的类型定义已经内置在react-router-dom包中,无需单独安装@types/react-router-dom,直接移除:yarn remove @types/react-router-dom清理缓存并重新安装依赖
rm -rf node_modules yarn.lock yarn install优化路由写法(可选)
嵌套路由的子路径可以省略根路径前缀,改为相对路径,写法更规范:const router = createBrowserRouter( createRoutesFromElements( <> <Route path="/login" element={<LoginPage />} /> <Route errorElement={<ErrorView />} path="/" element={<Layout />}> <Route path="stacks" element={<StackList />} /> <Route path="stacks/:name" element={<StackDetails />} /> <Route path="instances" element={<InstancesList />} /> <Route path="new" element={<NewInstance />} /> </Route> </> ) )
内容的提问来源于stack exchange,提问作者user672009
相关产品推荐
相关产品推荐

