【问题标题】:Conditional type based on value of other prop基于其他属性值的条件类型
【发布时间】:2020-06-09 09:51:32
【问题描述】:

在我的项目中,我有一个包含两个道具的组件:

collapsible,
onToggle

我很难在 TypeScript 中为这些道具创建一个类型。问题是,当可折叠为 true 时,我希望 onToggle 函数为 (): void,但如果可折叠为 false,我希望 onToggle 未定义。

我尝试过这样的事情:

type Props = {
  collapsible: boolean;
  onToggle: collapsible ? () => void : undefined;
}

但显然它不起作用,因为在定义 onToggle 类型时可折叠是未定义的。如何处理?这甚至可能让类型依赖于值吗?

【问题讨论】:

  • 你真的需要collapsible吗?你不能让onToggle 可选,并检查onToggle === undefined 是否?
  • 虽然这在布尔属性上使用有区别的联合是可行的,如下面的答案所示,你实际上对类型系统提出了太多要求。想象一下拥有collapsible: Math.random() > .5
  • 这是一个更普遍的问题,如果这样的事情是可能的。我知道在这种情况下很容易在组件内部检查它:)

标签: reactjs typescript toggle react-props react-typescript


【解决方案1】:

您可以使用有区别的联合(在collapsible 上有区别):

type Props = {
    common?: string
} & ({
    collapsible?: false;
} | {
    collapsible: true;
    onToggle: () => void
    })

function Test(p: Props) {
    return <></>
}

function Usage() {
    return <>
        <Test /> {/* Ok */}
        <Test collapsible={false} /> {/* Ok */}
        <Test collapsible={true} /> {/* Err, as expected */}
        <Test collapsible={true} onToggle={() => { }} /> {/* ok */}
    </>
}

Playground Link

【讨论】:

  • 这对于 Usage 函数中的道具非常有用。当您尝试访问Test 组件内的onToggle 函数时,您将收到以下错误:Property 'onToggle' does not exist on type 'Props'. Property 'onToggle' does not exist on type '{ common?: string | undefined; } &amp; { collapsible?: false | undefined; }'
【解决方案2】:

你的可折叠道具是布尔类型,所以它要么是假/真,

你不能这样做吗,

    type Props = {
     collapsible: boolean;
     onToggle():void | undefined;
   }

或,

      type Props = {
         collapsible: boolean;
         onToggle?():void;
       }

然后在实现时,您可以轻松检查 onToggle 是否未定义。因为如果某些东西是可选的并且没有提供,那么它在 TS 中默认是未定义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    相关资源
    最近更新 更多