我正在构建一个我想在其中显示文章的React网站(我称它们为“预览”)。
文章可以是文本,也可以是图像/视频。我宣布两个接口(TextPreviewProps和ImgVidPreviewProps某些共同的属性() ,id
),type
但也对其他人的不同(TextPreviewProps具有text
的特性,同时ImgVidPreviewProps有file
例如属性)。
export interface TextPreviewProps {
id: number;
type: "text";
text: string;
onChangeText?: (newText: string) => void;
}
export interface ImgVidPreviewProps {
id: number;
type: "image" | "video";
file: File;
}
export type ContentPreviewProps = TextPreviewProps | ImgVidPreviewProps;
我已经声明了类型别名ContentPreviewProps,它可以是TextPreviewProps或ImgVidPreviewProps。
我的呈现“预览”的函数将ContentPreviewProps用作输入,并且我希望它根据输入是Text还是Image / Video返回一个不同的React Component。由于我们不能真正地在Typescript中动态地进行类型检查,因此最好的方法是什么?
此刻,我检查type
属性是“ text”还是“ image” /“ video”,然后根据的值将ContentPreviewProps对象转换为TextPreviewProps或ImgVidPreviewPropstype
。
const renderPreview = (
content: ContentPreviewProps
): JSX.Element => {
const { type, id } = content;
if (type === "text") {
const textContent = content as TextPreviewProps;
return (
<TextPreview
type={type}
text={textContent.text}
onChangeText={(newText: string) => console.log(newText)}
id={id}
/>
);
}
const imgVidContent = content as ImgVidPreviewProps;
return (
<ImgVidPreview
type={type}
file={imgVidContent.file}
id={id}
/>
);
};
但是,这种方法存在冗余,因为我必须同时检查type
和根据检查结果转换对象。
在Typescript中在运行时实现此类特定于类型的行为的惯用方式是什么?
当您这样做时:
export type ContentPreviewProps = TextPreviewProps | ImgVidPreviewProps;
然后,从type
两者中的prop出发TextPreviewProps
,ImgVidPreviewProps
将确定将在type中指向哪一个ContentPreviewProps
。
因此,当您收到prop时type: string = "text"
,ContentPreviewProps
习惯上将是:
{
id: number;
type: "text";
text: string;
onChangeText?: (newText: string) => void;
}
因此,在使用时,您不必根据type
道具值进行投射!因为您在声明该类型时已经这样做了:
export type ContentPreviewProps = TextPreviewProps | ImgVidPreviewProps;
您可以将代码修改为:
从Ewaren进行的AS更新在下面,破坏type
掉content
是问题的原因。
const renderPreview = (
content: ContentPreviewProps
): JSX.Element => {
if (content.type === "text") { // TS won't complain about textContent.text since you are validating it here.
return (
<TextPreview
type={content.type}
text={content.text}
onChangeText={(newText: string) => console.log(newText)}
id={content.id}
/>
);
}
return (
<ImgVidPreview
type={content.type}
file={content.file}
id={content.id}
/>
);
};
我相信TS不会对此抱怨。因为您正在有条件地检查type
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句