如何避免在泛型中显式定义对象值类型?TypeScript技术问询
简化TypeScript枚举键的对象类型定义
当然可以简化这种重复的写法!你可以借助TypeScript的内置工具类型或者映射类型,避免逐个为枚举成员指定值类型,让代码更简洁易维护。
方案1:使用Record工具类型
Record<Keys, Type>是TypeScript专门用来生成“键为指定类型、值统一为另一种类型”的对象类型的工具,正好适配你的场景:
interface FlagModel { value: boolean; } interface GenericFlagsModel<T extends Record<string, FlagModel>> { flags: T } enum FLAG_NAMES { FLAG_FOO = 'flag-foo', FLAG_BAR = 'flag-bar' } // 简化后的写法,无需逐个指定每个键的FlagModel type CustomFlagsModel = GenericFlagsModel<Record<FLAG_NAMES, FlagModel>>
这样CustomFlagsModel的flags属性会自动包含FLAG_NAMES的所有枚举成员作为键,每个键的值类型都是FlagModel,和你原来的写法效果完全一致,但代码简洁了很多。
方案2:使用映射类型(更灵活的扩展方案)
如果你之后需要给个别枚举成员指定不同的值类型,映射类型会更方便。它的基础写法和Record效果一致,但扩展性更强:
// 基础简化写法 type CustomFlagsModel = GenericFlagsModel<{ [K in FLAG_NAMES]: FlagModel }> // 扩展示例:给特定flag修改值类型 type CustomFlagsModelWithVariant = GenericFlagsModel<{ [K in FLAG_NAMES]: K extends typeof FLAG_NAMES.FLAG_BAR ? { value: string } : FlagModel }>
这个写法的好处是,后续如果要调整某个flag的类型,直接在映射里做条件判断即可,不用修改整个对象结构。
效果验证
不管用哪种方式,最终生成的CustomFlagsModel类型和你原来手动写的完全等价:
- 可以通过
flags[FLAG_NAMES.FLAG_FOO]访问对应的flag - 每个flag的类型都是
FlagModel(或你自定义的变体类型)
内容的提问来源于stack exchange,提问作者tprieboj
相关产品推荐
相关产品推荐

