TypeScript嵌套函数扩展属性时泛型S无法解析问题
TypeScript
makeStyles 类型报错修复方案 报错核心原因
- 泛型参数
S未在makeStyles的泛型声明列表中定义,导致默认类型C = SxClasses<S>处TS无法解析S的类型 - 原代码错误将wrapper函数的入参类型定义为原始
P类型,实际wrapper内部接收的是注入themeVars后的扩展props,导致内部访问props.themeVars无类型提示 - 泛型设计冗余,多余的
C泛型增加了类型推导链路的复杂度,反而阻断了自动推导
修复后完整实现
// 按项目实际路径导入SxProps、Theme类型 import type { SxProps, Theme } from '@mui/material/styles'; // 项目中已定义的主题变量常量 declare const ThemeVars: { borderRadius: string; [key: string]: unknown }; // 样式对象类型:key为类名,值为Sx样式属性 type SxClasses<S> = { [className in keyof S]: SxProps<Theme> }; // 注入主题变量后的扩展props类型 type ExtendedProps<P> = P & { themeVars: typeof ThemeVars }; // makeStyles返回的样式生成函数类型 type SxClassesWrapper<P, T> = (props: P) => T; /** * 构建样式的工具函数 * @param wrapper 接收扩展props、返回样式对象的函数 * @returns 接收组件原始props、返回SxClasses类型样式对象的函数 */ export function makeStyles< P = {}, S extends Record<string, SxProps<Theme>> = Record<string, SxProps<Theme>> >(wrapper: (props: ExtendedProps<P>) => S): SxClassesWrapper<P, SxClasses<S>> { return (props: P) => { const extendedProps: ExtendedProps<P> = { ...props, themeVars: ThemeVars, }; return wrapper(extendedProps); }; }
使用示例
// 定义样式,传入自定义props类型,内部props自动识别themeVars和height属性 const useStyles = makeStyles<{ height: number }>((props) => ({ class1: { width: '100px', borderRadius: props.themeVars.borderRadius }, class2: { height: props.height } })); // 调用生成样式,classes自动推导类名,支持自动补全 const classes = useStyles({ height: 200 }); // classes.class1、classes.class2 均有完整类型提示
类型表现
- 编写wrapper回调时,
props自动获得ExtendedProps<P>类型,访问自定义属性、themeVars均有类型校验和提示 - 最终生成的
classes对象类型为SxClasses<S>,所有类名自动推导,输入时支持TS补全 - 无自定义props时可省略泛型参数,默认适配
P = {}场景
内容的提问来源于stack exchange,提问作者Vincent Peres
相关产品推荐
相关产品推荐

