添加Msal组件后Router/Redirect报TS2786无法作为JSX组件错误
React路由组件TS报错ts(2786)排查解决
问题场景
项目初始运行正常,在index.tsx新增MSAL相关组件、App.tsx引入PageLayout组件后,Router、Route、Redirect等路由组件位置全部触发TypeScript编译错误。
相关代码
App.tsx 核心代码
// 导入语句略 export default function App() { const { loading, theme, themeString, teamsfx } = useTeamsFx(); return ( <TeamsFxContext.Provider value={{theme, themeString, teamsfx}}> <PageLayout> <AuthenticatedTemplate> <ProfileContent /> </AuthenticatedTemplate> <UnauthenticatedTemplate> <p>您尚未登录,请先完成登录。</p> </UnauthenticatedTemplate> </PageLayout> <Provider theme={theme || teamsTheme} styles={{ backgroundColor: "#eeeeee" }}> <Router> <Route exact path="/"> <Redirect to="/tab" /> </Route> {loading ? ( <Loader style={{ margin: 100 }} /> ) : ( <> <Route exact path="/privacy" component={Privacy} /> <Route exact path="/termsofuse" component={TermsOfUse} /> <Route exact path="/tab" component={Tab} /> <Route exact path="/config" component={TabConfig} /> </> )} </Router> </Provider> </TeamsFxContext.Provider> ); }
index.tsx 核心代码
// 导入语句略 const msalInstance = new PublicClientApplication(msalConfig); ReactDOM.render( <React.StrictMode> <MsalProvider instance={msalInstance}> <App /> </MsalProvider> </React.StrictMode>, document.getElementById("root") );
报错信息
'Redirect' 无法作为JSX组件使用。
其实例类型'Redirect'不是有效的JSX元素,不同类型定义下render()方法的返回类型存在兼容问题:类型'React.ReactNode'无法赋值给项目本地路径node_modules/@types/react/index中定义的ReactNode类型,错误码为ts(2786)。
根因
- 依赖版本冲突:新增MSAL、TeamsFx相关依赖时,依赖树拉取了多份不同版本的
@types/react类型定义,TS编译时识别到两份不匹配的ReactNode类型,判定路由组件返回值不符合当前项目的JSX元素类型要求,这是该错误码最常见的触发原因。 - 路由版本语法不兼容:
react-router-domv6版本已移除Redirect组件,且Route组件的写法、嵌套规则和v5版本差异较大,如果安装依赖时自动升级到v6版本,也会触发组件识别错误。
解决步骤
- 第一步:统一React类型依赖版本
执行以下命令查看项目中存在的@types/react版本:
如果返回结果中存在多个不同版本号,在npm ls @types/reactpackage.json中添加配置强制全项目使用同一版本,版本号和项目原本使用的React主版本对齐:- npm 8及以上版本添加
overrides字段:"overrides": { "@types/react": "对应版本号,例如17.0.47" } - yarn环境添加
resolutions字段:"resolutions": { "@types/react": "对应版本号" }
node_modules目录、锁文件(package-lock.json/yarn.lock)后重新执行npm install/yarn install安装依赖。 - npm 8及以上版本添加
- 第二步:校验react-router-dom版本适配
执行以下命令查看当前安装的路由版本:npm ls react-router-dom- 如果是v5版本:检查导入语句,确认
Router、Route、Redirect均从react-router-dom包导入,没有和其他依赖的同名组件产生混淆。 - 如果是v6版本:替换废弃语法:
- 移除
Redirect组件,替换为Navigate组件,跳转逻辑添加replace属性 - 所有
Route组件必须包裹在<Routes>标签内 - 路由挂载的组件通过
element属性传入,不再使用component属性
修正后的路由代码示例:
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; <Router> <Routes> <Route path="/" element={<Navigate to="/tab" replace />} /> {loading ? ( <Route path="*" element={<Loader style={{ margin: 100 }} />} /> ) : ( <> <Route path="/privacy" element={<Privacy />} /> <Route path="/termsofuse" element={<TermsOfUse />} /> <Route path="/tab" element={<Tab />} /> <Route path="/config" element={<TabConfig />} /> </> )} </Routes> </Router> - 移除
- 如果是v5版本:检查导入语句,确认
- 第三步:清除TS缓存
VS Code中按下快捷键Ctrl+Shift+P(macOS为Cmd+Shift+P),调出命令面板后输入TypeScript: Restart TS Server回车,重启TS服务清除旧的类型缓存即可。
内容的提问来源于stack exchange,提问作者Harsh Shrivastava
相关产品推荐
相关产品推荐

