首页 > 解决方案 > 如何在打字稿中将对象类型转换为联合?

问题描述

例如,我有一个类型 EventMapping,它是一个映射“eventName -> eventData”。我需要将发出的事件存储在列表中。因此我想将此映射转换为事件类型,因此我无法将不正确类型的数据推送到事件列表中。

// type which i have
type EventMapping = {
  click: {
    position: Point;
  };
  scroll: {
    top: number;
    bottom: number;
  };
}

// type which i want to get
type Event = {
  type: 'click';
  data: {
    position: Point;
  };
} | {
  type: 'scroll';
  data: {
    top: number;
    bottom: number;
  };
}

// usage example
const events: Event[] = [];

// ok
events.push({
  type: 'scroll',
  data: {
    top: 0,
    bottom: 0,
  }
});

// error
events.push({
  type: 'click',
  data: {
    top: 0,
    bottom: 0,
  }
});

标签: typescripttypescript-generics

解决方案


我的策略是两个步骤:

  1. 将 EventMapping 类型转换为键的联合:所以目标是得到

    “滚动” | “点击”

    这可以通过keyof操作符来完成

  2. 从这个联合中,我将它映射到您的事件类型。使用这里提到的技巧:将联合映射到另一个联合类型

结果是:

type Distribute<U> = U extends keyof EventMapping? {type: U, data: EventMapping[U]} : never;

type Event = Distribute<keyof EventMapping>

推荐阅读