I'm changing a React component to Typescript. It calls an API. I believe my interfaces are set up correctly, but I'm not passing the types correctly.
How do I fix the two errors in the Parent below?
return <div>Error: {error.message}</div>; // "Object is possibly 'null'"{stories.results.map((story, idx) => { // "Object is possibly 'null' or 'undefined'"alt={ // Type 'string | null' is not assignable to type 'string | undefined'. Type 'null' is not assignable to type 'string | undefined'.
My Interfaces
export interface NewsProps {
results?: (ResultsEntity)[] | null;
}
export interface ResultsEntity {
section: string;
title: string;
abstract: string;
url: string;
multimedia?: (MultimediaEntity)[] | null;
}
export interface MultimediaEntity {
url: string;
caption: string;
alt:string;
}
Parent Component
import React, { FC, ReactElement, useEffect, useState } from "react";
import Story from "./Story";
const News: FC<NewsProps> = ({results:ResultsEntity}):ReactElement => {
const [error, setError] = useState(null);
const [stories, setStory] = useState<NewsProps>();
useEffect(() => {
const getCurrentPage = () => {
const url = new URL(window.location.href);
const page = url.pathname.split("/").pop();
return page ? page : "home";
};
const section = getCurrentPage();
fetch(
`https://api.nytimes.com/svc/topstories/v2/${section}.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr`
)
.then((res) => res.json())
.then((data) => {
setTimeout(() => setStory(data), 1500);
})
.catch((error) => {
setError(error);
});
}, []);
if (error) {
return <div>Error: {error.message}</div>; // "Object is possibly 'null'"
} else
if (!stories) {
return <div>Loading...</div>
} else {
return (
<>
<ul className="stories">
{stories.results.map((story, idx) => { // "Object is possibly 'null' or 'undefined'"
return (
<Story
key={idx}
title={story.title}
abstract={story.abstract}
img={story.multimedia[0].url}
alt={ // Type 'string | null' is not assignable to type 'string | undefined'. Type 'null' is not assignable to type 'string | undefined'.
story &&
story.multimedia &&
story.multimedia[0] &&
story.multimedia[0].caption
? story.multimedia[0].caption
: null
}
link={story.url}
/>
);
})}
</ul>
</>
);
}
}
export default News;
Child
import React, { FC, ReactElement } from "react";
interface StoryProps {
title?: String;
img?: string;
alt?: string;
abstract?: string;
link?: string;
}
const Story: FC<StoryProps> = ({title, img, alt, abstract, link}): ReactElement => {
return (
<div className="story">
<li className="story-title">{title}</li>
<span className="story-content">
<img className="story-img" src={img} alt={alt} />
<span>
<li className="story-body">{abstract}</li>
</span>
</span>
</div>
);
};
export default Story;