首页 > 解决方案 > 反应功能组件中的打字稿道具歧视

问题描述

我正在创建一个动态小部件,它可以是空的,也可以是填充的。默认情况下它应该是空的。什么时候populated={true},我希望totalGrosstotalNet值是必需的。否则,这两个道具不应该被允许。

为此,我尝试使用区分类型 ( WidgetBodyProps)。但是,TypeScript 抱怨因为totalNet&totalGross是必需的道具<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 错误? TS 错误

标签: javascriptreactjstypescripttypeerror

解决方案


一旦你解构了道具,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 };

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

工作示例


推荐阅读