我正在尝试在 React 应用程序中添加 TypeScript。
版本:
"react": "16.9.0",
"typescript": "3.5.3",
我有一个像这样的数组
import aLogo from '../images/a.svg';
import bLogo from '../images/b.svg';
const websites = [
{
name: 'A',
src: aLogo,
url: 'https://a.com',
},
{
name: 'B',
src: bLogo,
url: 'https://b.com',
},
];
我通过 props 将它传递给组件。
interface Website {
name: string;
src: string;
url: string;
}
interface Props {
websites: Website[];
}
const SocialList: React.FC<Props> = (props: Props) => {
const { websites } = props;
return websites.map((website) => {
const { name, src, url } = website;
return (
<a key={name} href={url}>
<img src={src} />
</a>
);
});
};
但是它给了我错误
TypeScript error in /SocialList.tsx(16,7):
Type '(props: Props) => Element[]' is not assignable to type 'FunctionComponent<Props>'.
Type 'Element[]' is missing the following properties from type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>': type, props, key TS2322
14 | }
15 |
> 16 | const SocialList: React.FC<Props> = (props: Props) => {
| ^
我阅读了 how do you declare an array of objects inside typescript? 中的答案,但仍然不知道如何修复它。
最佳答案
您的 SocialList
组件呈现多个节点。虽然 React 版本 >=16.0 支持此行为,但 React 的类型声明 (@types/react
) 不允许这种行为。换句话说,在 JS React (v16+) 中可以渲染多个节点,但在 TS React 中则不行。对于JS React,请参阅相关问题:Return multiple elements inside React.render() .
要解决此问题,您有几个选择:更新组件以使其仅返回单个节点、使用类型断言或禁用 TypeScript 中的错误。
返回单个节点
您可以更新代码以返回包含元素中的 a
标记。过去默认使用 div
,但这会使 DOM 变得困惑。相反,您可以使用 React.Fragment
组件,它不会向实际 DOM 渲染任何内容,因此基本上就是您所追求的。
示例:
const SocialList: React.FC<Props> = (props: Props) => {
const { websites } = props;
const websiteElements = websites.map((website) => {
const { name, src, url } = website;
return (
<a key={name} href={url}>
<img src={src} />
</a>
);
});
return (
<React.Fragment>
{websiteElements}
</React.Fragment>
)
};
您还可以使用short syntax for fragments如果您愿意,如下所示:
<>
{websiteElements}
</>
类型断言
您可以断言返回值的类型为any
,这将导致类型错误被忽略。然而,这将与 eslint 规则 no-explicit-any 发生冲突。如果您启用了该功能(这是我不同意的规则)。无论如何,我不推荐这种方法,因为您应该尽可能避免asany
(这里是可以避免的)。
示例:
const SocialList: React.FC<Props> = (props: Props) => {
const { websites } = props;
return websites.map((website) => {
const { name, src, url } = website;
return (
<a key={name} href={url}>
<img src={src} />
</a>
);
}) as any;
};
禁用错误
由于错误只是由于 @types/react
的类型声明造成的,因此您可以 suppress the TS error将 //@ts-ignore
放在错误行上方。您可以尝试找到要忽略的更具体的错误,但在这种情况下我找不到它,所以要小心,因为这将忽略该行上的所有 TS 错误(例如,如果 Props
接受类型参数,但未给出类型参数)。
我不推荐这种方法,因为应尽可能避免禁用 TS 错误,并且来自the TypeScript docs :
Please note that this comment only suppresses the error reporting, and we recommend you use this comments very sparingly.
示例:
// @ts-ignore
const SocialList: React.FC<Props> = (props: Props) => {
const { websites } = props;
return websites.map((website) => {
const { name, src, url } = website;
return (
<a key={name} href={url}>
<img src={src} />
</a>
);
});
};
关于reactjs - 类型 '(props: Props) => Element[]' 不可分配给类型 'FunctionComponent<Props>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651621/