React+TypeScript+Material-UI使用withStyles类组件报not assignable错误
报错触发原因
该报错是TypeScript对withStyles高阶组件的类型推导异常导致的:
- 你定义的
App组件Props继承了WithStyles<typeof styles>,相当于将classes等样式注入属性标记为了组件的必填入参 withStyles高阶组件本身会在内部完成classes等属性的自动注入,这些属性不需要外部使用者主动传入- 你没有对导出的组件做额外的类型标注,TypeScript无法感知注入属性已经被HOC处理,会误认为你调用
<App />时需要主动传入样式相关属性,你传入空对象就触发了类型不匹配报错,报错中出现的JSSFontface相关提示是类型推导混乱后的异常输出。
修复方案
方案1:快速标注导出类型
直接在导出时明确告诉TypeScript,包装后的App组件不需要外部传入任何参数,修改导出代码即可:
export default withStyles(styles)(App) as React.ComponentType<{}>;
如果后续需要给App传递自定义属性,把泛型中的{}替换为你定义的自定义Props接口即可。
方案2:拆分内外属性(更规范)
将组件的内部使用属性和外部传入属性拆分定义,符合TypeScript的类型设计规范:
// 定义外部传入属性,无外部属性则留空 interface ExternalProps {} // 定义组件内部使用的全量属性 = 外部属性 + 样式注入属性 interface InternalProps extends ExternalProps, WithStyles<typeof styles> {} interface State { open: boolean; } class App extends React.Component<InternalProps, State> { // 原有组件逻辑完全不需要改动 constructor(props: InternalProps) { super(props); this.state = { open: false }; } // ... 其余逻辑保持不变 } // 导出时指定组件对外暴露的Props类型 export default withStyles(styles)(App) as React.ComponentType<ExternalProps>;
额外排查点
如果修改后仍有报错,可以检查以下两点:
- 确认你引入的
WithStyles、Theme、createStyles都来自同一版本的MUI包,v4版本从@material-ui/core/styles引入,v5版本从@mui/styles引入 - 如果你使用的是MUI v5,建议优先使用
styledAPI替代withStyles做样式注入,类型兼容问题更少。
内容的提问来源于stack exchange,提问作者A. Boz
相关产品推荐
相关产品推荐

