如果定义了其他属性,则 Typescript 需要该属性 (requiredIf)

hyp*_*erN 6 typescript reactjs

是否可以在 TS 中定义interfaceor a type,这将确保如果A定义了 prop,则 propB也必须是(如果A未定义/设置,则B也不能是)。例如我有某事。喜欢:

export interface IExample {
  a: string;
  b: () => void;
  c: boolean;
}
Run Code Online (Sandbox Code Playgroud)

然后,如果我有一些实现的对象,IExample我希望 TS 允许我只拥有 propc或两者ab并且c如果我只有aandcband 则抛出编译错误c

更好的例子是在 React 组件中使用它,就像在这个 SO 问题中一样,或者更好的是我想实现相同的功能,例如:this ReactPropType library

我试图通过歧视性工会来做到这一点,但我无法让它发挥作用,而且当我有几个像这样的道具(即requriedIf)时,它会变得太复杂,但也许我只是做错了。这是我的代码示例:

export interface INetworkRequestStatusMessageDefaultProps {
  testID?: string;
  networkRequestStatus: NetworkRequestStatus;
}
export interface INetworkRequestStatusMessageLoadingProps {
  loadingMessageTranslationKey: string;
  firstTimeUserMessageTranslationKey: string;
  firstTimeUserCallOnActionTranslationKey: string;
  onPressFirstTimeUser: () => void;
  dataLoaded: boolean;
  errorMessageTranslationKey: never;
  errorCallOnActionTranslationKey: never;
  networkErrorMessageTranslationKey: never;
  onPressError: () => never;
  deviceConnectedToNetwork: never;
}
export interface INetworkRequestStatusMessageFisrtTimeUserProps {
  firstTimeUserMessageTranslationKey: string;
  firstTimeUserCallOnActionTranslationKey: string;
  onPressFirstTimeUser: () => void;
  dataLoaded: boolean;
  loadingMessageTranslationKey: never;  
  errorMessageTranslationKey: never;
  errorCallOnActionTranslationKey: never;
  networkErrorMessageTranslationKey: never;
  onPressError: () => never;
  deviceConnectedToNetwork: never;
}
export interface INetworkRequestStatusMessageErrorProps {
  errorMessageTranslationKey: string;
  errorCallOnActionTranslationKey: string;
  networkErrorMessageTranslationKey: string;
  onPressError: () => void;
  deviceConnectedToNetwork: boolean;
  firstTimeUserMessageTranslationKey: undefined;
  firstTimeUserCallOnActionTranslationKey: never;
  onPressFirstTimeUser: () => never;
  dataLoaded: never;
  loadingMessageTranslationKey: never;
}

export type NetworkRequestStatusMessageProps =
  | (INetworkRequestStatusMessageDefaultProps &
      (
        | INetworkRequestStatusMessageLoadingProps
        | INetworkRequestStatusMessageFisrtTimeUserProps
        | INetworkRequestStatusMessageErrorProps))
  | (INetworkRequestStatusMessageDefaultProps &
      INetworkRequestStatusMessageErrorProps &
      INetworkRequestStatusMessageFisrtTimeUserProps &
      INetworkRequestStatusMessageLoadingProps);
Run Code Online (Sandbox Code Playgroud)

这是我的使用方法:

 <NetworkRequestStatusMessage
            networkRequestStatus={this.props.networkRequestStatus}
            deviceConnectedToNetwork={this.props.deviceConnectedToNetwork}
            dataLoaded={this.props.savedWorkoutsLoaded}
            errorCallOnActionTranslationKey={"savedWorkouts.retry"}
            errorMessageTranslationKey={"savedWorkouts.error"}
            firstTimeUserCallOnActionTranslationKey={"savedWorkouts.callOnActionGoToCW"}
            firstTimeUserMessageTranslationKey={"savedWorkouts.firstTimeUser"}
            loadingMessageTranslationKey={"savedWorkouts.loading"}
            networkErrorMessageTranslationKey={"savedWorkouts.networkError"}
            onPressError={this.props.load}
            onPressFirstTimeUser={() => {
              tron.log("Clicked on go to CW");
            }}
            testID={"SAVED_WORKOUTS"}
          />
Run Code Online (Sandbox Code Playgroud)

但 TS 对我大喊大叫:

types of property 'firstTimeUserMessageTranslationKey' are incompatible.
        Type 'string' is not assignable to type 'undefined'
Run Code Online (Sandbox Code Playgroud)

我的代码背后的整个想法是确保开发人员使用时NetworkRequestStatusMessage必须指定所有道具或例如所有这些道具(或全部都不指定):errorMessageTranslationKeyerrorCallOnActionTranslationKeynetworkErrorMessageTranslationKeyonPressError以及类似的INetworkRequestStatusMessageFisrtTimeUserProps

Nur*_*yev 4

您应该为此使用联合:

type Example = {
  a: string;
  b: () => void;
  c: boolean;
} | {
  c: boolean;
}
Run Code Online (Sandbox Code Playgroud)