【问题标题】:How do I define a TypeScript type for React props where prop B is only accepted if prop A is passed to a component?如何为 React 道具定义 TypeScript 类型,其中仅当道具 A 传递给组件时才接受道具 B?
【发布时间】:2019-04-26 18:46:51
【问题描述】:

我的组件 Text 有 2 个道具:isHideable: booleanhidden: boolean。仅当isHideabletrue 时,我如何允许Hidden 作为道具?

目前,我同时接受 isHideablehidden,这不太理想:

type Props = {
  children: React.ReactNode;
  isHideable?: boolean;
  hidden?: boolean;
};

const Text: React.FC = ({ children, isHideable, hidden }: Props) => {
  if (!isHideable && hidden) {
    console.log("No, you can’t do that.")
  }

  return (
    <span isHideable={isHideable} hidden={hidden}>
      {children}
    </span>
  );
};

部分解决方案

我觉得 the solution here 可能是与使用 TypeScript 的 Parameters&lt;F&gt; type alias 一起使用的答案,但我无法将它们拼凑在一起。

我为什么不想使用联合类型来解决这个问题?

我相信这可以使用联合类型来解决:


type IsHideable = {
  isHideable: true;
  hidden?: boolean;
}

type IsNotHideable = {
  isHideable?: false;
}

type Props = {
  children: React.ReactNode;
} & (IsHideable | IsNotHideable);

但我想避免这种情况,因为如果接受 props 的条件变得更复杂,工会会更加混乱(例如,如果我希望 prop D 的接受依赖于 prop C,prop C 依赖于 prop B,prop B支持 A)。

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    我认为联合是表达您的意图的唯一正确方式。对于您担心的混乱,您可以使用 union & union 操作来处理它,以产生交集类型的并集,见下文:

    type IHideability = { isHideable?: false } | { isHideable: true, hidden?: boolean }
    
    type IEditability = { isEditable?: false } | { isEditable: true, readonly?: boolean }
    
    type Props = IHideability & IEditability & { children: React.ReactNode };
    

    【讨论】:

    • “正确”的方式可能是functional overloading - 以前没听说过。调查一下。
    • @StephenKoo 区分联合和函数重载都解决了您的问题,但方式不同。对于你的情况,我认为有区别的工会更好。
    • @StephenKoo 函数重载更多地关注外部,如果您将错误的参数传递给函数,它会报告错误。但是在函数体内,当你定义函数时,你并没有有用的代码建议和类型检查。
    • 这是一个有趣的话题,当应用于函数参数时,区分联合与函数重载的优缺点。它需要整篇文章来探索所有细节。
    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2020-12-22
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2020-01-25
    • 2021-06-23
    相关资源
    最近更新 更多