如何创建泛型对象数组,使每个对象的泛型类型对应特定枚举值?
如何创建每个元素对应特定枚举值的泛型对象数组?
现有以下代码,尝试为不同枚举值定义对应的插件配置类型,但当前数组类型PluginConfig<ServicePlugin>[]的表现不符合预期:
enum ServicePlugin { Plugin1, Plugin2, Plugin3, } interface PluginOptions { [ServicePlugin.Plugin1]: { option1: string }; [ServicePlugin.Plugin2]: { option1: number; option2: number }; } type PluginOptionsMap = Omit< { [key in ServicePlugin]: undefined }, keyof PluginOptions > & PluginOptions; type PluginConfig<T extends ServicePlugin> = PluginOptionsMap[T] extends undefined ? { plugin: T } : { plugin: T; options: PluginOptionsMap[T]; }; // 当前写法存在问题:类型错误无法被正确检测 const params: PluginConfig<ServicePlugin>[] = [ { plugin: ServicePlugin.Plugin1, options: { option1: "foo", }, }, { plugin: ServicePlugin.Plugin2, options: { option1: 123, option2: 456, }, }, { plugin: ServicePlugin.Plugin2, options: { option1: "bar", // 此处类型错误未被提示 }, }, { plugin: ServicePlugin.Plugin3, // 错误:不该要求 options,但当前类型却报错 }, ];
问题在于PluginConfig<ServicePlugin>会将泛型T解析为整个枚举的联合类型,导致生成的是一个包含所有可能属性的联合对象,而非每个元素对应单个枚举值的精准配置。
解决方案
我们需要生成一个由每个枚举值对应的PluginConfig类型组成的联合类型,再将数组元素设为这个联合类型,这样TypeScript就能对每个数组元素进行精准的类型检查。
方法1:通过映射类型生成联合类型
定义一个包含所有单个插件配置的联合类型:
// 生成所有单个PluginConfig的联合类型 type PluginConfigUnion = { [K in ServicePlugin]: PluginConfig<K> }[ServicePlugin]; // 使用联合类型数组 const params: PluginConfigUnion[] = [ { plugin: ServicePlugin.Plugin1, options: { option1: "foo", }, }, { plugin: ServicePlugin.Plugin2, options: { option1: 123, option2: 456, }, }, { plugin: ServicePlugin.Plugin2, options: { option1: "bar", // ✅ 现在会正确提示类型错误:类型“string”不能赋值给类型“number” }, }, { plugin: ServicePlugin.Plugin3, // ✅ 此处不再报错,符合预期(Plugin3无options要求) }, ];
方法2:直接使用分布条件类型简化定义
也可以通过分布条件类型直接生成联合类型,避免额外定义PluginConfigUnion:
// 直接定义数组类型为所有单个PluginConfig的联合数组 const params: Array<PluginConfig<ServicePlugin[keyof ServicePlugin]>> = [ // 同上正确的配置示例 ];
原理说明
当泛型参数是联合类型时,TypeScript的分布条件类型会自动遍历联合中的每个成员,生成对应的类型后再合并为联合。通过{ [K in ServicePlugin]: PluginConfig<K> }[ServicePlugin],我们先创建一个以枚举值为键、对应配置为值的映射类型,再通过索引访问获取所有值的联合,这样每个数组元素都会被限定为单个枚举值对应的精准配置。
内容的提问来源于stack exchange,提问作者Mitchell Loeppky
相关产品推荐
相关产品推荐

