如何在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
相关产品推荐
相关产品推荐

