如何解决如何使用 Typescript 将对象传递给子自定义 React 功能组件
感谢您花时间阅读本文。
我正在尝试使用带有 AirBnB 配置的 eslint 来学习 Typescript。像映射对象数组并为每个对象创建自定义功能组件这样简单的事情给了我下一个错误:
Argument of type '(product: ProductType) => JSX.Element' is not assignable to parameter of type '(value: object,index: number,array: object[]) => Element'.
这是父组件ProductGrid:
const ProductGrid: React.FC = () => {
const products = [
{
id: "string1",name: "string1",price: {
formatted_with_symbol: "string1"
},description: "string1",},...
];
return (
<div>
<Grid container spacing={3}>
<Grid item xs={12} md={6} lg={4}>
{products.map((product: ProductType) => (
<Product key={product.id} product={product} />
))}
</Grid>
</Grid>
</div>
);
};
export default ProductGrid;
这是子组件Product:
const Product: React.FC<ProductTypeAsProps> = ({product}: ProductTypeAsProps) => {
const [loading,setLoading] = useState(true);
setTimeout(() => {
setLoading(false);
},3000);
return (
<Box className="product">
<Card className="card">
<CardContent className="content">
{loading ? (
<div className="skeleton">
<Skeleton
variant="text"
animation="wave"
component="h2"
width="65%"
/>
</div>
) : (
<div>
<p>{product.name}</p>
<p>{product.description}</p>
<p>{product.price.formatted_with_symbol}</p>
</div>
)}
</CardContent>
</Card>
</Box>
);
};
export default Product;
和类型声明:
export type ProductType = {
id: string;
name: string;
price: {
formatted_with_symbol: string;
};
description: string;
assets: [
{
id: string;
filename: string;
url: string;
}
];
};
export interface ProductTypeAsProps {
product: ProductType;
}
{
"extends": ["airbnb-typescript","react-app","prettier"],"parser": "@typescript-eslint/parser","parserOptions": {
"sourceType": "module","project": "tsconfig.json"
},"plugins": ["prettier","@typescript-eslint","react-hooks"],"settings": {
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
}
}
},"rules": {
"@typescript-eslint/no-explicit-any": [
"error",{
"ignoreRestArgs": true
}
],}
}
和 tsconfig :
{
"compilerOptions": {
"target": "es5","lib": ["es6","dom","dom.iterable","esnext"],"allowJs": true,"skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"strict": true,"forceConsistentCasingInFileNames": true,"noFallthroughCasesInSwitch": true,"module": "esnext","moduleResolution": "node","resolveJsonModule": true,"isolatedModules": true,"noEmit": true,"jsx": "react-jsx","noImplicitAny": false
},"include": ["src"]
}
我已经创建了 this codesandbox 但当然,lint 错误没有出现在那里,我在 VsCode 中编写了这个代码。
有什么帮助吗?因为这在 javascript 中是非常标准的。
解决方法
我可以通过查看错误消息来判断问题所在:
“(product: ProductType) => JSX.Element”类型的参数不可分配给“(value: object,index: number,array: object[]) => Element”类型的参数。
这表示您在 products.map()
中使用的地图函数的类型为 (product: ProductType) => JSX.Element
。它说这不是您的 products
数组的有效映射器,因为 products.map()
需要类型为 (value: object,array: object[]) => Element
的映射函数。
为什么会这样?
此错误意味着实际代码中的 products
变量的类型为 object[]
。您正试图通过在 (product: ProductType)
中使用 map()
来弥补这种模糊的类型,但这不起作用。在此处输入参数意味着您的 map 函数只能处理 ProductType
类型的对象,但它需要处理任何 object
,因为 products
是 object
的数组。
您需要做的是使您的 products
变量具有 ProductType[]
类型。我认为您是从实际代码中的 API 获取这些数据?因此,请确保 API 调用返回 ProductType[]
而不是 object[]
。
作为一种快速解决方法,您可以在映射之前声明数组的类型,但最好从源头解决问题。
{(products as ProductType[]).map((product) => (
<Product key={product.id} product={product} />
))}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。