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

TypeScript映射对象内联合类型实现关联字段类型校验

问题原因

当前写法没有建立厂商和对应可选颜色的绑定关系,最终生成的是所有厂商、所有颜色自由组合的类型,无法实现联动校验:

  • CarType是两个车型配置对象组成的联合类型
  • 直接访问联合类型的属性时,TS会将所有成员的对应属性合并为联合类型,最终得到{ manufacturer: "audi" | "mercedes", color: "red" | "blue" | "black" },自然不会限制厂商和颜色的匹配关系。
实现方案

要实现字段联动校验,需要生成可辨识联合类型:为每个厂商单独生成匹配其专属颜色的对象结构,再将所有合法结构组合为联合类型。

写法1:直接遍历配置对象的key生成类型

不需要额外定义冗余的中间类型,直接基于as const修饰的常量推导即可:

const cars = {
    "audi": {
        manufacturer: "audi",
        colors: ["red", "blue"]
    },
    "mercedes": {
        manufacturer: "mercedes",
        colors: ["blue", "black"]
    }
} as const

type Car = {
    [K in keyof typeof cars]: {
        manufacturer: (typeof cars)[K]["manufacturer"]
        color: (typeof cars)[K]["colors"][number]
    }
}[keyof typeof cars]

写法2:保留原有Mapper泛型结构

如果需要保留通用的Mapper类型,可通过条件类型触发TS对联合类型的分发特性:联合类型传入泛型时,会被拆分为单个成员逐个计算,最后合并计算结果:

const cars = {
    "audi": {
        manufacturer: "audi",
        colors: ["red", "blue"]
    },
    "mercedes": {
        manufacturer: "mercedes",
        colors: ["blue", "black"]
    }
} as const

type CarType = typeof cars[keyof typeof cars]

type Mapper<C extends CarType> = C extends C ? {
    manufacturer: C["manufacturer"]
    color: C["colors"][number]
} : never

type Car = Mapper<CarType>
校验效果

两种写法的校验效果完全一致:

// 校验通过:audi可选red/blue
const car1: Car = {
    manufacturer: "audi",
    color: "red"
}
// 校验通过:mercedes可选blue/black
const car2: Car = {
    manufacturer: "mercedes",
    color: "black"
}
// 校验报错:audi没有black配色
const car3: Car = {
    manufacturer: "audi",
    color: "black" // TS会直接抛出类型不匹配错误
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:01:11