首页 > 解决方案 > 如何为 React 道具定义 TypeScript 类型,其中仅当道具 A 传递给组件时才接受道具 B?

问题描述

我的组件Text有 2 个道具:isHideable: booleanhidden: boolean. 我如何仅在is时才允许Hidden作为道具?isHideabletrue

目前,我接受了两者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>
  );
};

部分解决方案

我觉得这里的解决方案可能是使用 TypeScript 的Parameters<F>type alias的答案,但我无法将它们拼凑在一起。

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

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


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

type IsNotHideable = {
  isHideable?: false;
}

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

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

标签: reactjstypescript

解决方案


我认为工会是表达您的意图的唯一正确方式。关于你担心的混乱,你可以用 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 };

推荐阅读