【问题标题】:How to write conditional types properly with react?如何使用反应正确编写条件类型?
【发布时间】:2020-03-22 22:35:37
【问题描述】:

所以我正在尝试编写一种道具类型格式,其中如果选择了一个道具,则另一个道具将被丢弃。

type ButtonProps = {
    to: string,
} | {
    onClick: (() => void) 
};

export const BackButton = (props: ButtonProps) => {
  if(props.to != null) {
     //props {to} will be used hence no need for onClick
  }
  else {
    // {onClick} will be used over {to} 
  }
}

但它说

“ButtonProps”类型上不存在“to”属性。 类型 '{ onClick: () => void; 上不存在属性 'to' }'.ts(2339`

如何格式化类型的形状,或者选择任何一个类型时,另一个将被丢弃。没有可选项,选择的道具是必需的。

【问题讨论】:

  • 您可以将to 作为可选属性type ButtonProps { to?: string, onClick?: () => void }。另外,我想界面更适合这里

标签: reactjs typescript react-typescript


【解决方案1】:

我们需要使用类型保护来根据条件适当地缩小类型。为此,我们需要稍微拆分类型,以便在类型保护 + 可读性中进行断言。 ButtonProps 下面与您的实现相同,但有明确指定的联合元素。

第二件事是类型保护,在isButtonWithTo下面的sn-p中就是这样。它将类型缩小到联合中的选项之一。注意is关键字,它表示函数计算结果为true的含义,在这种情况下我是说如果isButtonWithTo将返回true,那么参数的类型为ButtonWithTo

type ButtonWithTo = {
    to: string,
}
type ButtonWithClick = {
    onClick: (() => void) 
}
// the same type as orginal but with explicit declarations of union elements
type ButtonProps = ButtonWithTo | ButtonWithClick 


const isButtonWithTo = (b: ButtonProps): b is ButtonWithTo  => 'to' in b // type guard

export const BackButton = (props: ButtonProps) => {
  if(isButtonWithTo(props)) {
     props // props have type ButtonWithTo
  } else {
    props // props have type ButtonWithClick
  }
}

【讨论】:

    猜你喜欢
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    相关资源
    最近更新 更多