I need only few properties from the received object. Is it possible to map through received data and remove unnecessary properties using Typescript interface?
Example of data:
[
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
}
]
Desired object properties (Typescript Interface):
interface IMovie {
overview: string,
release_date: Date,
title: string
}
My attepmt to write mapper function:
const movieMapper = (movies: []): [IMovie] => {
return movies.map(movie => <IMovie>movie);
}
CodePudding user response:
Your return type is a tuple, not an array.
You can use object destructuring to pick the fields and map to a new object.
const movieMapper = (movies: any[]): IMovie[] => {
return movies.map(({overview, release_date, title}) => ({ overview, release_date, title}));
}
console.log(movieMapper(movies))
CodePudding user response:
Using io-ts you could write this codec:
// 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)
then when you receive the response, you can guard it with the codec
// 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
})
I know this answer goes a bit beyond what you asked but keep in mind that runtime checking anything coming from outside your code is recommended!
CodePudding user response:
You can have a two interfaces: for actual api response array items and desire items:
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'>
You can have a Movie
as a independent type, but it's rather to be dependent from original one so in case the MovieFull
will change, Movie
will also change.
Next you can perform mapping:
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 }));
}