繁体   English   中英

Typescript 反应功能组件中的道具歧视

[英]Typescript prop discrimination in react functional component

我正在创建一个动态小部件,它可以是空的也可以是已填充的。 它应该默认为空。 populated={true}时,我希望需要totalGrosstotalNet值。 否则,不应允许使用这两个道具。

为此,我正在尝试使用区分类型( WidgetBodyProps )。 然而,TypeScript 抱怨因为totalNettotalGross<WidgetBodyPopulated />中必需的道具

type WidgetBodyProps =
    | { isEmpty?: false; totalNet: string; totalGross: string }
    | { isEmpty: true; totalNet?: never; totalGross?: never };

type WidgetProps = WidgetHeaderProps & WidgetBodyProps;

const Widget = (props: WidgetProps) => {
    const { title = "", isEmpty = true, totalNet, totalGross } = props;

    return (
        <Card>
            <Box>
                <WidgetHeader title={title} />
                <Divider my="4" />
                {isEmpty ? (
                    <WidgetBodyEmpty flex="1" />
                ) : (
                    <WidgetBodyPopulated totalNet={totalNet} totalGross={totalGross} />
                )}
            </Box>
        </Card>
    );
};

如何修复此 Typescript 错误? 错误

一旦你解构了道具,Typescript 就会忘记它们曾经是相关的。 因此,对一个变量的测试不会区分另一个变量的类型。 但是在你解构props的时候你还没有测试它的类型,所以所有的变量都是以所有的可能性被类型化的。

但是,如果你避免解构,那么 Typescript 可以密切关注props的类型。 通过这种方式测试道具的属性可以缩小您期望的道具类型。

{props.isEmpty ? (
    <WidgetBodyEmpty flex="1" />
) : (
    <WidgetBodyPopulated
      totalNet={props.totalNet}
      totalGross={props.totalGross}
    />
)}

然后你甚至可以将这些道具简化为:

type WidgetBodyProps =
    | { isEmpty?: false; totalNet: string; totalGross: string }
    | { isEmpty: true };

因为您永远不会在不先检查.isEmpty的情况下访问.totalNet

工作示例

通常发生此错误是因为 Typescript 不相信您某些东西不是 null。使用非空断言运算符告诉 Typescript 它可以相信您知道自己在做什么,并且您不会向它提供 null。另一种选择是确保相关变量正确设置为空字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM