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

TypeScript实现根据对象属性值动态匹配关联类型的方法

问题原因

你当前写法中,ApiFormats[Block.type]会被直接解析为TextApiFormat | ImageApiFormat的联合类型,无法和同对象下的block.type字段建立绑定关系,因此TS无法根据block.type的取值自动收窄apiFormat的类型,自然实现不了联动约束。

实现方案

核心思路是通过映射类型遍历所有合法的type值,为每个type单独生成匹配的结构,最终将所有结构组合为联合类型,利用TS的可辨识联合特性实现字段联动。
完整实现代码:

type TextApiFormat = {
  title: string
}

type ImageApiFormat = {
  src: string
}

export type ApiFormats = {
  text: TextApiFormat
  image: ImageApiFormat
}

export type Block = {
  id: string
  type: keyof ApiFormats
}

// 联动类型核心实现
export type EditBlock = {
  [K in keyof ApiFormats]: {
    block: Block & { type: K }
    apiFormat: ApiFormats[K]
  }
}[keyof ApiFormats]
实现效果

最终EditBlock会被推导为两个专属结构的联合类型:

  • 当block.type为text时,apiFormat自动匹配为TextApiFormat
  • 当block.type为image时,apiFormat自动匹配为ImageApiFormat

使用时TS会自动做类型校验和收窄:

// 合法赋值无报错
const validTextBlock: EditBlock = {
  block: {
    id: '1',
    type: 'text'
  },
  apiFormat: {
    title: '文本标题'
  }
}

// 类型不匹配时直接抛出错误
const invalidBlock: EditBlock = {
  block: {
    id: '2',
    type: 'image'
  },
  apiFormat: {
    title: '错误的字段' // 此处TS报错:image类型不存在title字段
  }
}

// 条件判断中自动收窄类型
function processBlock(editBlock: EditBlock) {
  if (editBlock.block.type === 'text') {
    // 此处TS自动推导apiFormat为TextApiFormat,可直接访问title
    console.log(editBlock.apiFormat.title)
  } else {
    // 此处TS自动推导apiFormat为ImageApiFormat,可直接访问src
    console.log(editBlock.apiFormat.src)
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:45:39