我是软件开发和打字稿的新手,所以请原谅我代码中的任何暴行。
** 我有三种类型,其中一种是工会。**
类型.ts
export type CoachType = {
id: number,
firstName: string,
type: string,
lastName: string,
email: string,
city: string,
state: string,
picture: string
reviews: Array<{id: number; title: string; body: string; rating: number; likes: Array<{id: number; agree: boolean}>}>
}
export type ReviewType = {
id: number,
rating: number,
type: string,
title: string,
body: string,
likes: Array<{id: number; agree: boolean}>
}
export type CardType = CoachType | ReviewType;
export type ReviewsInterface = {
reviews: ReviewType[]
}
**然后,我检查传递给组件的 props,查看 type 属性,以有条件地渲染一些 JSX。 **
index.tsx
import * as React from "react";
import { useNavigate } from "react-router-dom";
import { styled } from "@mui/material/styles";
import Card from "@mui/material/Card";
import CardHeader from "@mui/material/CardHeader";
import CardMedia from "@mui/material/CardMedia";
import CardContent from "@mui/material/CardContent";
import CardActions from "@mui/material/CardActions";
import Avatar from "@mui/material/Avatar";
import IconButton, { IconButtonProps } from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import { red } from "@mui/material/colors";
import FavoriteIcon from "@mui/icons-material/Favorite";
import { CardType, ReviewType } from "../../common/types";
interface ExpandMoreProps extends IconButtonProps {
expand: boolean;
}
const ExpandMore = styled((props: ExpandMoreProps) => {
const { expand, ...other } = props;
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? "rotate(0deg)" : "rotate(180deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
}));
export default function CoachCard(props: CardType) {
const [expanded, setExpanded] = React.useState(false);
const navigate = useNavigate();
const averageRating = (reviews: Array<ReviewType>): string => {
const numberOfRatings = reviews.length;
let totalOfReviews = 0;
for (let i = 0; i < numberOfRatings; i++) {
totalOfReviews += reviews[i].rating;
}
const average = totalOfReviews / numberOfRatings;
return `Average Rating: ${average}/10`;
};
const handleExpandClick = () => {
setExpanded(!expanded);
};
console.log(props, "checking props")
return(
<>
{ props.type === 'coach' ? (
<Card sx={{ width: 345 }}>
<CardHeader
className="cardHeader"
onClick={() => navigate(`/coach/${props.id}`)}
avatar={
<Avatar sx={{ bgcolor: red[500] }} aria-label="recipe">
R
</Avatar>
}
title={`${props.firstName} ${props.lastName}`}
subheader={averageRating(props.reviews)}
/>
<CardMedia
component="img"
height="194"
image={props.picture}
alt="Coach"
/>
<CardContent>
<Typography variant="body2" color="text.secondary">
<div>City: {props.city}</div>
<div>State: {props.state}</div>
<div>Email: {props.email}</div>
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<ExpandMore
expand={expanded}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="show more"
>
{/* <ExpandMoreIcon /> */}
</ExpandMore>
</CardActions>
</Card>
) : (
<Card sx={{ width: 345 }}>
<CardHeader
className="cardHeader"
onClick={() => navigate(`/coach/${props.id}`)}
avatar={
<Avatar sx={{ bgcolor: red[500] }} aria-label="recipe">
R
</Avatar>
}
title={`${props.firstName} ${props.title}`}
subheader={props.title}
/>
<CardContent>
<Typography variant="body2" color="text.secondary">
<div>City: {props.title}</div>
<div>State: {props.body}</div>
<div>Email: {props.body}</div>
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<ExpandMore
expand={expanded}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="show more"
>
{/* <ExpandMoreIcon /> */}
</ExpandMore>
</CardActions>
</Card>
)}
</>
)
}
它说错了
“CardType”类型上不存在属性“firstName”。 类型“ReviewType”上不存在属性“firstName”。
else 语句中继续出现错误,表示几乎相同,只是 CoachType 和 CardType 上不存在某些道具
我尝试过使用 switch case 和其他条件渲染方法,但没有任何效果。我检查了各种帖子和文档,但无法弄清楚我搞砸了什么。非常感谢任何帮助。
将属性
type
设置为 'coach'
或 'review'
而不是 string
,例如,对于 Coach Type,不要执行 type: string
放置 type: 'coach'
,然后进行审查 type: 'review'
,这将允许 Typescript 缩小类型。
例如。 打字稿游乐场