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或两者a,b并且c如果我只有aandc或band 则抛出编译错误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必须指定所有道具或例如所有这些道具(或全部都不指定):errorMessageTranslationKey,errorCallOnActionTranslationKey,networkErrorMessageTranslationKey,onPressError以及类似的INetworkRequestStatusMessageFisrtTimeUserProps
您应该为此使用联合:
type Example = {
a: string;
b: () => void;
c: boolean;
} | {
c: boolean;
}
Run Code Online (Sandbox Code Playgroud)