如何为tss-react自定义函数参数添加类型以获取样式智能提示?
问题描述
我正在使用tss-react和MUI包,编写了一个合并通用样式与组件特定样式的自定义函数,但无法确定函数参数应设置的类型。访问classes对象时会出现TypeScript错误(例如:“Property 'colorRed' does not exist on type 'Record<never, string>'”)。请问需要在getUseStyles.ts文件中添加什么类型,才能同时获取commonStyles和组件样式的类型,让TypeScript/编辑器在访问classes对象的键(如classes.colorRed或classes.colorBlue)时提供智能提示?
代码示例
Test.tsx
const useStylesHook = getUseStyles( // 合并组件样式与通用样式 (theme) => { return { colorRed: { color: 'red', }, colorBlue: { color: 'blue', }, } }) export default function Test() { const { classes, cx } = useStylesHook() return ( <h1 className={cx(classes.colorRed, classes.padding20, classes.colorBlue)}> Testing this color </h1> ) }
commonStyles.ts
export const commonStyles = (theme) => { return { padding20: { paddingTop: '20px', }, } }
getUseStyles.ts
export const getUseStyles = ( styles: any, // 这里应该添加什么类型? customStyles?: any, ) => { return makeStyles()((theme) => { return { ...commonStyles(theme), ...styles(theme, { ...customStyles }), } }) }
解决方案
要解决这个问题,需要通过泛型类型让TypeScript自动推导并合并通用样式与组件自定义样式的类型,具体步骤如下:
1. 补全通用样式的类型定义
先给commonStyles添加类型声明,明确其返回值类型,方便后续合并使用:
// commonStyles.ts import { Theme } from '@mui/material/styles'; // 提取通用样式的返回类型 export type CommonStyles = ReturnType<typeof commonStyles>; export const commonStyles = (theme: Theme) => { return { padding20: { paddingTop: '20px', }, }; };
2. 给getUseStyles添加泛型与参数类型
修改getUseStyles.ts,用泛型捕获组件样式的类型,并与通用样式类型合并:
// getUseStyles.ts import { makeStyles } from 'tss-react/mui'; import { Theme } from '@mui/material/styles'; import { commonStyles, CommonStyles } from './commonStyles'; // 定义组件样式函数的统一类型:接收Theme和自定义参数,返回样式对象 type ComponentStyleFn<T = {}> = (theme: Theme, customStyles: T) => Record<string, React.CSSProperties>; export const getUseStyles = <T extends {}, S extends ReturnType<ComponentStyleFn<T>>>( styles: ComponentStyleFn<T>, customStyles?: T, ) => { // 合并通用样式与组件样式的类型 return makeStyles<CommonStyles & S>()((theme) => { return { ...commonStyles(theme), ...styles(theme, customStyles || {}), }; }); };
3. 组件中的类型自动推导
现在在组件中调用getUseStyles时,TypeScript会自动合并通用样式和组件自定义样式的类型,classes对象会包含padding20、colorRed、colorBlue的完整智能提示:
// Test.tsx import { getUseStyles } from './getUseStyles'; import { Theme } from '@mui/material/styles'; const useStylesHook = getUseStyles((theme: Theme) => { return { colorRed: { color: 'red', }, colorBlue: { color: 'blue', }, }; }); export default function Test() { const { classes, cx } = useStylesHook(); return ( <h1 className={cx(classes.colorRed, classes.padding20, classes.colorBlue)}> Testing this color </h1> ); }
关键说明
- 泛型
S用于捕获组件自定义样式的返回类型,CommonStyles & S实现了两种样式类型的合并 ComponentStyleFn统一了组件样式函数的签名,确保其符合接收Theme和可选自定义参数的规范- 补全
theme的Theme类型(来自@mui/material/styles),让样式函数内部也能获得MUI主题的智能提示
内容的提问来源于stack exchange,提问作者Rohan Sharma
相关产品推荐
相关产品推荐

