我有这个数据库,在使用Map函数时我正在尝试正确地映射类型。第一次这样做是为了尝试学习,但我被困住了。
Db
const db = {
data: [
{
id: 1,
contentType: ['video'],
title: '1 to 1 Coaching: Sprinting Technique',
author: {
name: 'James',
image: {
alt: 'smiling.',
},
},
image: {
alt: 'Two footballers jostling for the ball with a coach watching in the background.',
},
},
],
}
现在我仅使用id
和title
的样本类型,但即使在这里,我仍然停留在如何正确映射它们的位置上,以便TS不会抱怨:(
App.tsx
type Data = {
id: number
title: string
}
interface Customer {
id: number
title: string
}
export default function Box(): JSX.Element {
const [data, setData] = useState([db])
return (
<>
{data.map(
({
data: {
id,
contentType,
title,
author: {
name,
img: { src, alt },
},
image: { src, alt },
},
}): JSX.Element => {
console.log(id)
return <div css={mainBox}></div>
},
)}
</>
)
}
答案 0 :(得分:1)
此问题与TS本身无关,因为错误是由于map
回调的参数列表中的对象分解引起的。
当您将对象分解应用于函数的参数时,JS / TS会将对象的属性分配给具有相同名称的不同变量(除非它们是对象并且它们以相似的方式被分解)。
让我们看一下author
属性的构造:
...
author: {
name,
img: { src, alt },
},
...
此代码段将按以下方式处理:
author.name
属性将分配给不同的name
变量。但是,
author.img
不会被分配给不同的img
变量,因为它是一个对象并且已解构。
它的属性将分别分配给不同的变量src
和alt
。
此后,我们破坏了另一个属性:
image: { src, alt },
同样,image
将不会分配给不同的变量,因为它的对象已被解构。但这应该是属性。
它的属性是src
和alt
。并且应该将它们设置为具有这些名称的变量,但是我们已经有那些名称来自解构author.img
。
因此,变量定义中存在名称冲突,这就是TS编译器引发错误的原因。
您可以通过将属性分配给新变量名称来解决此问题,例如,通过以下方式:
({
data: {
id,
contentType,
title,
author: {
name,
img: { src: authorImgSrc, alt: authorImgAlt },
},
image: { src, alt },
},
}): JSX.Element => {
// src refers to image.src, authorImgSrc refers to author.name.src
// alt refers to image.alt, authorImgAlt refers to author.name.alt
}
在这里,我们为具有不同名称的变量显式分配了author.img
属性,因此不再存在名称冲突。
解构分配技术可能确实有用,MDN上有更多示例
此后,您可能首先发现甚至不需要map
,因为您在此处使用了数组解构:
const [data] = useState([db]);
然后,您可以直接访问其内部:
const {img} = data.data.author;
因此,您可能要删除.map
(并直接渲染数据库条目)或不使用data
变量初始化中的数组解构:
const data = useState([db]);