如果定义了other,则打字稿需要该属性(requiredIf)

时间:2019-02-08 06:39:19

标签: reactjs typescript

是否可以在TS中定义interfacetype,以确保如果定义了道具A,道具B也必须(如果{{ 1}}未定义/设置,A也不可以)。例如,我有东西。喜欢:

B

然后,如果我有一些实现export interface IExample { a: string; b: () => void; c: boolean; } 的对象,我想让TS允许我只拥有道具IExample或同时拥有ca和{{1 }},如果我只有bcac,则抛出编译错误。

更好的示例是在React组件中使用此功能,例如this SO question,甚至更好的是,我想实现相同的功能,例如:this ReactPropType library

我试图通过区分工会来做到这一点,但是当我有几个这样的道具(即b)时,我无法使其正常工作,并且变得太复杂了,但也许我只是在做所有这一切错误。这是我的代码示例:

c

这是我的使用方式:

requriedIf

但是TS对我大喊大叫:

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);

我的代码背后的整个想法是确保如果使用 <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"} /> 的开发人员必须指定所有道具或例如所有这些道具(或都不选择):types of property 'firstTimeUserMessageTranslationKey' are incompatible. Type 'string' is not assignable to type 'undefined' ,{{ 1}},NetworkRequestStatusMessageerrorMessageTranslationKey,以及类似的errorCallOnActionTranslationKey

1 个答案:

答案 0 :(得分:1)

您应该为此使用联合:

type Example = {
  a: string;
  b: () => void;
  c: boolean;
} | {
  c: boolean;
}