将一种类型映射到另一种类型

时间:2019-09-16 15:44:38

标签: typescript

这是我经常遇到的问题。将一种类型转换为另一种的最佳方法是什么?一个可能的用例是扩展来自服务器的具有UI特定属性的对象。

interface RawData {
  id: number
  someOtherData: string
}

interface ViewData extends RawData {
  isVisible: boolean
}

const rawData: RawData = getDataFromServer() // Returns data with type RawData
const viewData: ViewData = mapRawDataToViewData(rawData)

function mapRawDataToViewData (rawData: RawData): ViewData {
  return {
    id: rawData.id,
    someOtherData: rawData.someOtherData,
    isVisible: Math.random() >= 0.5
  }
}

上面的示例有效,但是当处理非常大的对象时,尤其是在处理可能偶尔更改的服务器数据时,这会带来一些维护上的麻烦。我不仅需要更新一个接口,还需要更新map函数。

在纯JavaScript中,我将编写类似下面的函数。鉴于我将完全更改实现以适合TypeScript,因此我猜必须有一个更好的方法。是否可以复制所有现有属性并添加其他属性?我会在以下内容中添加什么类型?

function mapRawDataToViewData (rawData) {
  const viewData = copy(rawData) // Returns a copy so as not to mutate the original rawData
  viewData.isVisible = Math.random() >= 0.5
  return viewData
}

1 个答案:

答案 0 :(得分:2)

您可以使用Typescript's object spread syntax

缩短复制属性的时间

例如:

function mapRawDataToViewData (rawData: RawData): ViewData {
  return {
    ...rawData,
    isVisible: Math.random() >= 0.5
  }
}

这样,RawData的所有项目都被复制到返回的对象中,而您只需要复制ViewData的其他属性。而且,如果您想覆盖基础的一种属性(在您的情况下为RawData),则可以在 传播基础的属性之后进行,像这样-

function mapRawDataToViewData (rawData: RawData): ViewData {
  return {
    ...rawData,
    someOtherData: "Overriden value",
    isVisible: Math.random() >= 0.5
  }
}