You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:09:14