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

如何在不使用对象联合类型时严谨定义TypeScript的MediaData类型

解决方案:严谨定义MediaData类型(不使用手动对象联合)

方案一:泛型+条件类型实现类型绑定

通过泛型关联type字段取值,搭配条件类型自动匹配对应meta类型,既保证类型严谨性,又避免手动编写对象联合分支:

// 定义媒体类型的字面量联合
type MediaType = 'audio' | 'video';

// 根据type字段自动推导对应的meta类型
type MediaMeta<T extends MediaType> = T extends 'audio' ? AudioMeta : VideoMeta;

// 最终的MediaData泛型类型
type MediaData<T extends MediaType = MediaType> = {
  type: T;
  meta: MediaMeta<T>;
};

使用示例

// 指定类型时,meta会强制匹配对应结构
const audioData: MediaData<'audio'> = {
  type: 'audio',
  meta: { rate: 44100, codec: 'mp3', duration: 120 } // 必须符合AudioMeta结构
};

const videoData: MediaData<'video'> = {
  type: 'video',
  meta: { width: 1920, height: 1080, codec: 'h264', duration: 120 } // 必须符合VideoMeta结构
};

// 不指定类型时,自动推导为严谨的联合类型
const mediaData: MediaData = Math.random() > 0.5 ? audioData : videoData;

方案二:映射类型自动生成严谨联合类型

如果场景允许使用联合类型,但不想手动编写每个对象分支,可通过映射类型自动生成等价的严谨联合类型:

// 建立媒体类型与元数据类型的映射关系
type MediaMetaMap = {
  audio: AudioMeta;
  video: VideoMeta;
};

// 基于映射类型生成最终的MediaData
type MediaData = {
  [K in keyof MediaMetaMap]: {
    type: K;
    meta: MediaMetaMap[K];
  };
}[keyof MediaMetaMap];

该方式生成的MediaData与你原本手动编写的对象联合类型完全等价,但维护性更强——后续新增媒体类型时,只需修改MediaMetaMap即可。

补充:非联合结构的运行时校验

如果场景必须使用type和meta均为联合类型的单一对象结构,可通过类型守卫在运行时校验,配合类型定义实现严谨性:

// 类型守卫函数,判断meta是否属于AudioMeta
function isAudioMeta(meta: AudioMeta | VideoMeta): meta is AudioMeta {
  return 'rate' in meta;
}

// 业务逻辑中使用类型守卫做类型推断
function processMedia(data: MediaData) {
  if (data.type === 'audio' && isAudioMeta(data.meta)) {
    // 此处data.meta会被TS推断为AudioMeta
    console.log(data.meta.rate);
  } else if (data.type === 'video') {
    // 此处data.meta会被TS推断为VideoMeta
    console.log(data.meta.width);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:45:31