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

如何创建泛型对象数组,使每个对象的泛型类型对应特定枚举值?

如何创建每个元素对应特定枚举值的泛型对象数组?

现有以下代码,尝试为不同枚举值定义对应的插件配置类型,但当前数组类型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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:13:35