reactjs - Objekt eller Boolean hur man deklarerar typ i Typescript
Stötte på detta typdeklarationsproblem i React.
interface MessageCardProps {
message: {
id: string;
title: string;
content: string;
attachments: string[];
interest_count: number;
};
}
const MessageCard: FC<MessageCardProps> = ({
message: { id, title, content, attachments, interest_count },
}) => {
// ERROR: Type 'string | false' is not assignable to type 'boolean | { url: string; }'.
const image: { url: string } | boolean =
attachments.length > 0 ? attachments[0] : false;
return (
{/* Property 'url' does not exist on type 'true | { url: string; }'.*/}
{image && <img className={style.img} src={image.url} alt="timeline" />}
);
};
export default MessageCard;
Vad är rätt sätt att deklarera typen av const image? Det kan antingen vara ett objekt med URL-egenskapen eller en boolean.
Svar #1
Det första problemet är att attachments[0] kommer att returnera en sträng, inte ett objekt med en url-egenskap. Så du kan använda typen string | boolean. Finns det en specifik anledning till att du vill omsluta det i ett objekt?
Om du använder string | boolean kan du göra src={image}
Redigera:
Du skulle till och med kunna förbättra detta ännu mer genom att helt enkelt inte använda boolean alls, och istället använda faktumet att null är ett falskt värde. Då kan du göra så här.
const image: string = attachments.length > 0 ? attachments[0] : null;
return (
{image && <img className={style.img} src={image} alt="timeline" />}
);
Redigera 2:
Det visar sig att attachments-egenskapen i MessageCardProps inte ska vara en array av strängar, utan en array av objekt med en egenskap som kallas "URL". Så här bör det alltså se ut:
interface MessageCardProps {
message: {
id: string;
title: string;
content: string;
attachments: {URL: string}[];
interest_count: number;
};
}
Nu, för att få den första bilden, kan du göra så här:
const image: string = attachments.length > 0 ? attachments[0].URL : null;
Svar #2
Jag antar att du vill att bilden endast ska sättas om attachments[0] är satt?
om ja, skulle jag skriva på det här sättet. (det finns snabbare och enklare sätt att göra det, men denna kod använder typunioner och typeof):
const attachments:Array<string> = ["/test"]
interface IImage {url:string | boolean }
const image : IImage = attachments.length > 0 ? {url:attachments[0]} : {url:false}}
return(
{image && typeof image.url==='string' && image.url!=="" && (<p>I have a valid url</p>)}
)
