'TypeScript. The function accepts two different objects, but returns one object
I am beginner in TypeScript. I am developing a home project - a weather application, I have two requests to the server, the responses are almost identical, except for the "feels_like" field. So, before applying the fields in the component, I run the server response through the mapper, in which I leave only the fields I need, but I can't implement it so that it is scalable and typescript doesn't swear)
This is my code:
export const mapWeatherProps = (data?: IWeatherAPI | IWeatherSearchingPlaceAPI): IWeatherUserGeo | undefined => {
if (!data) {
return undefined
}
return {
id: data.id,
location: data.name,
condition: data.cod,
country: data.sys.country,
date: data.dt,
description: data.weather[0].description,
feels_like: data.main.feels_like,
humidity: data.main.humidity,
icon_id: data.weather[0].id,
sunrise: data.sys.sunrise,
sunset: data.sys.sunset,
temperature: Math.round(data.main.temp),
temperature_min: Math.round(data.main.temp_min),
temperature_max: Math.round(data.main.temp_max),
wind_speed: Math.round(data.wind.speed * 3.6),
}
}
Interfaces:
export interface IWeatherAPI {
"coord": {
"lon": number,
"lat": number
},
"weather": [
{
"id": number,
"main": string,
"description": string,
"icon": string
}
],
"base": string,
"main": {
"temp": number,
"feels_like": number,
"temp_min": number,
"temp_max": number,
"pressure": number,
"humidity": number,
},
"visibility": number,
"wind": {
"speed": number,
"deg": number,
"gust": number
},
"clouds": {
"all": number
},
"dt": number,
"sys": {
"type": number,
"id": number,
"country": string,
"sunrise": number,
"sunset": number,
},
"timezone": number,
"id": number,
"name": string,
"cod": number
}
export interface IWeatherSearchingPlaceAPI {
"coord": {
"lon": number,
"lat": number,
},
"weather": [
{
"id": number,
"main": string,
"description": string,
"icon": string,
}
],
"base": string,
"main": {
"temp": number,
"pressure": number,
"humidity": number,
"temp_min": number,
"temp_max": number,
},
"visibility": number,
"wind": {
"speed": number,
"deg": number,
},
"clouds": {
"all": number,
},
"dt": number,
"sys": {
"type": number,
"id": number,
"message": number,
"country": string,
"sunrise": number,
"sunset": number,
},
"id": number,
"name": string,
"cod": number,
}
export interface IWeather {
"country": string,
"condition": number
"description": string,
"date": number,
"humidity": number,
"id": number,
"icon_id": string | number,
"location": string,
"sunrise": number,
"sunset": number,
"temperature": number,
"temperature_min": number,
"temperature_max": number,
"wind_speed": number,
"weather_icon"?: string,
}
export interface IWeatherUserGeo extends IWeather {
feels_like: number,
}
Component:
...
interface ICityProps {
weather?: IWeatherUserGeo,
weekForecast?: IForecast,
isGeoConfirm: boolean,
}
const City: FC<ICityProps> = ({ weather, isGeoConfirm, weekForecast }) => {
if (!weather) {
return null
}
const { location, temperature, temperature_min, temperature_max, description, wind_speed, humidity, sunrise, sunset, feels_like } = weather
return (
<section className="city">
<div className="city__lead">
<div className="city__main">
<div className="city__flex-wrapper">
flag
<h2 className="city__title">
{location}
{isGeoConfirm &&
<FontAwesomeIcon className="city__icon city__icon_type_navi" icon={faLocationArrow}/>
}
</h2>
</div>
<p className="city__temp">{Math.floor(temperature)}°</p>
<p className="city__temp">{Math.floor(feels_like)}°</p>
...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
