Material-UI makeStyles传props时出现TS2339属性不存在报错
报错根本原因
makeStyles是MUI封装的Hook式样式方法,在TypeScript环境下,它的泛型存在默认空值配置:如果调用时没有显式声明传入的props类型,所有样式规则回调里接收到的props参数,都会被自动推导为空对象类型{}- 空对象类型上不存在任何自定义业务属性,因此当尝试读取
props.backgroundColor、props.color这类自定义字段时,TypeScript就会抛出TS2339: 属性'X'不存在于'{}'类型上的错误 - 代码中
bar规则的写法不符合MUI的API规范:MUI支持的样式规则函数形式,需要以props为入参、返回完整的CSS样式对象,不能将单个CSS属性的取值单独写成嵌套函数,这种错误写法也会干扰TS的类型推导,加剧类型报错
修复方案
- 为
makeStyles显式声明泛型参数,明确传入的props结构
先定义清楚传入useStyles的props的TS接口,明确每个字段的名称与对应类型,再将这个类型传入makeStyles的泛型位,替换默认的空对象推导结果。
修正后的参考代码:import React from 'react'; import { makeStyles } from '@material-ui/core'; // 定义样式依赖的props类型 interface StyleProps { backgroundColor: string; color: string; } // 给makeStyles指定泛型:传入的props类型 const useStyles = makeStyles<StyleProps>({ // 直接将整个样式规则作为接收props的函数 foo: props => ({ backgroundColor: props.backgroundColor, }), // 修正错误写法:将整个bar的样式对象作为函数返回值,不再单独把color属性写成嵌套函数 bar: props => ({ color: props.color, }), }); function MyComponent() { // 模拟传入的props const props = { backgroundColor: 'black', color: 'white' }; // 传入props时,TS会自动匹配之前定义的StyleProps类型 const classes = useStyles(props); return <div className={`${classes.foo} ${classes.bar}`} /> } export default MyComponent; - 校验规则自动生效
完成泛型定义后,TypeScript会自动完成两层类型校验:- 校验传入
useStyles的props是否完全匹配定义的结构,字段缺失、类型不匹配都会提前给出提示 - 校验样式规则中读取的props属性是否真实存在,不再将props推导为空对象
- 校验传入
内容的提问来源于stack exchange,提问作者Hongli Bu
相关产品推荐
相关产品推荐

