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

如何在TypeScript中为MUI按钮变体生成器定义部分严格类型键

实现TypeScript下可选的键类型约束(基于MUI按钮变体)

我正在用TypeScript结合MUI组件构建扩展变体的辅助函数,现有代码如下:

import { ButtonProps, ButtonPropsSizeOverrides } from "@mui/material";

declare module "@mui/material/Button" {
  interface ButtonPropsVariantOverrides {
    light: true;
  }
}

type ButtonVariant = ButtonProps["variant"];

const buttonVariants: readonly Exclude<ButtonVariant, undefined>[] = [
  "contained",
  "outlined",
  "light",
  "text",
] as const;

之前用{ [key: string]: () => void }作为返回类型时代码能正常运行,但一次拼写错误让我意识到需要实现类型安全:返回对象的键必须是buttonVariants中的成员,不能是任意字符串。

尝试下面的写法后,TypeScript报错提示缺少text、outlined、contained等属性:

type VariantMakerKey = typeof buttonVariants[number];

const makeVariants = (): { [key in VariantMakerKey]: () => void } => {
  return {
    light: () => {},
  };
};

解决方案

要实现「键必须属于指定集合,但无需全部声明」的约束,只需将映射类型的属性改为可选即可,有两种写法:

写法1:使用Partial工具类型

Partial<T>会把类型T的所有属性转为可选,直接套在原映射类型外层:

type VariantMakerKey = typeof buttonVariants[number];

const makeVariants = (): Partial<{ [key in VariantMakerKey]: () => void }> => {
  return {
    light: () => {},
    // 可自由添加/删减buttonVariants内的键,比如加contained: () => {}也合法
  };
};

写法2:直接在映射类型中添加可选标记?

在键的遍历后加?,显式声明每个属性都是可选的:

type VariantMakerKey = typeof buttonVariants[number];

const makeVariants = (): { [key in VariantMakerKey]?: () => void } => {
  return {
    light: () => {},
  };
};

效果验证

  • 若拼写错误(比如写ligth: () => {}),TypeScript会直接报错,因为该键不在VariantMakerKey集合中
  • 仅声明部分变体(比如只保留light)不会触发缺失属性的错误
  • 无法添加不在buttonVariants中的键,完全实现类型安全

内容的提问来源于stack exchange,提问作者brandonscript

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:10:34