我正在将 React 组件更改为 Typescript。它调用一个 API。我相信我的接口(interface)设置正确,但我没有正确传递类型。
如何修复下面父级中的两个错误?
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'.
我的界面
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;
}
父组件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;
最佳答案
对于 error
,问题是当你创建状态时,你没有明确地给它一个类型,所以 typescript 必须尝试推断类型。它看到你传入了 null,所以它假设状态是(并且永远是)null
:
const [error, setError] = useState(null);
如果您知道错误将是什么,您可以给出一个表示该错误的类型。例如:const [error, setError] = useState<null | { message: string }>(null);
如果您什么都不知道,那么您可能需要求助于 any
:const [error, setError] = useState<any>(null);
对于
stories
,您已经定义了 .results
属性可能为 null 或未定义:export interface NewsProps {
results?: (ResultsEntity)[] | null;
}
...但是您在使用它之前不会检查这些值。您需要编写代码来检查这些情况。例如,如果您只想跳过 map 语句并且不渲染任何内容,您可以这样做:{stories.results && stories.results.map((story, idx) => {
或者与可选链接相同的东西(需要 typescript 3.7 或更高版本):{stories.results?.map(story, idx) => {
对于
alt
Prop ,你传入null
,但这不是 alt
的合法值.传入undefined
反而。alt={
story &&
story.multimedia &&
story.multimedia[0] &&
story.multimedia[0].caption
? story.multimedia[0].caption
: undefined
}
或使用可选链接:alt={story?.multimedia?.[0]?.caption}
关于reactjs - typescript / react : "Object is possibly ' null'",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66400875/