繁体   English   中英

Typescript 将 API 中的数据转换为特定类型

[英]Typescript convert data from API into specific type

我只需要收到的对象的几个属性。 是否可以使用 Typescript 接口映射接收到的数据并删除不必要的属性?

数据示例:

[
  0: {
    "original_language" : "en",
    "title" : "The First Title",
    "original_title" : "The First Original Title",
    "overview": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac suscipit nulla.",
    "release_date": "2022-05-04",
    "popularity": 9411.64
  },
  1: {
    "original_language" : "en",
    "title" : "The Second Title",
    "original_title" : "The Second Original Title",
    "overview": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac suscipit nulla.",
    "release_date": "2022-05-04",
    "popularity": 9411.64
  },
  2: {
    "original_language" : "es",
    "title" : "The Third Title",
    "original_title" : "The Third Original Title",
    "overview": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac suscipit nulla.",
    "release_date": "2022-05-04",
    "popularity": 9411.64
  }
]

所需的对象属性(Typescript 接口):

interface IMovie {
  overview: string,
  release_date: Date,
  title: string
}

我尝试编写映射器函数

const movieMapper = (movies: []): [IMovie] => {
  return movies.map(movie => <IMovie>movie);
}

您的返回类型是元组,而不是数组。

您可以使用对象解构来选择字段并映射到新对象。

const movieMapper = (movies: any[]): IMovie[] => {
    return movies.map(({overview, release_date, title}) => ({ overview, release_date, title}));
}

console.log(movieMapper(movies))

您可以有两个接口:用于实际 api 响应数组项和期望项:

interface MovieFull {
  original_language: string
  title: string
  original_title: string
  overview: string
  release_date: Date
  popularity: number
}

type Movie = Pick<MovieFull, 'overview' | 'release_date', 'title'>

您可以将Movie作为独立类型,但它更依赖于原始类型,因此如果MovieFull发生变化, Movie也会发生变化。

接下来您可以执行映射:

const movieMapper = (movies: MovieFull[]): Movie[] => {
  return movies.map(movie => ({
    overview: movie.overview,
    release_date: movie.release_date,
    title: movie.title,
  }));
}
// or, using decostruction
const movieMapper = (movies: MovieFull[]): Movie[] => {
  return movies.map(({ overview, release_date, title }) => ({ overview, release_date, title }));
}

使用io-ts你可以编写这个编解码器:

// Codec file
import * as t from 'io-ts'

export const movieCodec = t.type({
  overview: t.string,
  release_date: t.string, // check out custom codecs to get dates as JS Date objects on decoding
  title: t.string,
})

export const movieListCodec = t.array(movieCodec)

然后当您收到响应时,您可以使用编解码器对其进行保护

// where you get the response
fetch(someEndpoint)
  .then<unknown>(r => r.json())
  .then(movieCodecList.is)
  .then(verifiedResponse => {
    // verifiedResponse is correctly typed AND it has been actually verified at runtime
  })

我知道这个答案有点超出您的要求,但请记住,建议运行时检查来自您的代码之外的任何内容!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM