typescript 界面中的条件 prop

uqzxnwby  于 2023-02-20  发布在  TypeScript
关注(0)|答案(1)|浏览(117)

我有一个关于接口的问题:
基本上,我创建了一个动态组件,它根据页面的不同而变化。我的界面是这样构造的:

interface Props {
heading: string;
description: string;
signUp?: boolean;
signUpButton1?: string;
signUpButtonLink1?: string;
signUpButton2?: string;
signUpButtonLink2?: string;
startFreeAccount?: boolean;
startFreeAccountSignUpButton?: string;
startFreeAccountLink1?: string;
startFreeAccountSignUpLink1?: string;
startFreeAccountSignUpLink2?: string;
startFreeAccountSignUpLink3?: string;
contactUsForDemo?: boolean;
contactUsForDemoInput1?: string;
contactUsForDemoInput2?: string;
contactUsForDemoInput3?: string;
contactUsForDemoButtonText?: string;
ThanksForDemo?: boolean;
ThanksForDemoButton?: string;
}

在我的代码中,我使用例如:

{props.signUp && 
          <div className="mt-10 flex flex-col  items-center gap-x-6">
            <Link
              href={"/signUpPractitioner/startFreeAccount"}
              className=" bg-black mb-4 -ml-[14vw] px-16 py-1.5 text-base font-semibold leading-7 text-white shadow-sm  outline outline-offset-0 outline-black"
            >
              {props.signUpButton1}
              
            </Link>
            <Link href={"/practitioner/contactUsForDemo"} 
            className=" bg-white -ml-[14vw] px-10 py-1.5 text-base font-semibold leading-7 text-black outline outline-offset-0 outline-black     shadow-sm"
>
               {props.signUpButton2} <span aria-hidden="true">→</span>
            </Link>
          </div> }

设置"signUp == true"将显示组件上面部分的信息。我的问题是链接(来自NEXTJS)无法处理"signUpButtonLink1"可能未定义的事实。如果我输入"signUpButtonLink1"必须有一个值,那么即使我不使用组件的"signUp"部分,我仍然需要为"signUpButtonLink1"赋值,这显然没有意义(就当前接口的构造方式而言,它有意义,但就功能而言,它没有意义)。
我的问题是:是否可以设置"signUp === true"时才需要设置"signUpButton1,signUpLink1 etc etc"?界面中所有的bool以及与之"关联"的 prop 都一样。
谢谢你的帮忙!

e5nqia27

e5nqia271#

您可以使用简单的联合来执行此操作

type Props = {
  heading: string;
  description: string;
} & (
  | {
      signUp?: false
      signUpButton1?: never
      // ...
    }
  | {
      signUp: true
      signUpButton1: string
      // ...
    }
) & (
  | {
    startFreeAccount?: false;
    startFreeAccountSignUpButton?: never;
    // ...
  }
  | {
    startFreeAccount: true;
    startFreeAccountSignUpButton: string;
    // ...
  }
) & (
  ...
)

也许可以添加一个实用程序类型:

type OptionalProps<K extends string, T> = 
  | { [key in K]?: false } & { [key in keyof T]?: never }
  | { [key in K]: true } & T

type Props = {
  heading: string
  description: string
}
  & OptionalProps<'signUp', {
    signUpButton1: string,
  }>
  & OptionalProps<'startFreeAccount', {
    startFreeAccountSignUpButton: string
  }>
  & ...

带有?: never的属性不是必需的,但是如果你把props分解成单独的变量,它们会让你的工作变得更简单。没有?: never你就不能这么做,它会告诉你对象中不存在名为...的属性。
或者你可以只使用对象而不是行内 prop :

type Props = {
  heading: string
  description: string
  signUp?: {
    button1: string
    button2: string
    // ...
  }
  startFreeAccount?: {
    signUpButton: string
    // ...
  }
  // ...
}

我甚至认为这些对象更易于阅读和使用

相关问题