是否有可能创建一个接口,其属性类型根据另一个属性更改,而不显式地在编译时知道它?
我希望能够根据对象的另一个属性推断对象的属性类型,而不必像Newtype那样声明T。而是声明Newtype并从属性推断T。见下图:
export interface Action {
type: K;
payload: K extends "UPDATE_FIVE_DAY"
? {
fiveDayForecast?: FiveDayForecast;
fiveDayExpiresAt?: Moment;
fiveDayLocationFor?: Location;
}
: K extends "UPDATE_LOADING"
? { loading: boolean }
: K extends "UPDATE_LOCATION"
? { location: Location }
: K extends "UPDATE_SETTINGS"
? { settings: Settings }
: undefined;
}
我遇到的问题是变量K
不存在,我可以这样设置它:
export interface Action<K extends 'UPDATE_FIVE_DAY' | 'UPDATE_LOADING' | ...etc
但是,我需要声明action.type的类型,我不一定知道。我想使用如下类型:
我要在通用减速器中使用此操作:
export default (state: State = initialState, action: Action): State => {
switch (action.type) {
case "UPDATE_LOADING":
return {
...state,
loading: action.payload,
};
}
});
但是,Return语句会抛出一个类型错误,因为它认为action.payload可能是任何可能的返回类型。这不是真的。
解决方案
我按照@shlang的建议,使用区别对待的联合使其正常工作。
减速机:
export default (state: State = initialState, action: Actions): State => {
switch (action.type) {
case "UPDATE_LOADING":
return {
...state,
loading: action.payload.loading,
};
}
});
和操作的类型:
export type Action = {
type: AllActionTypes;
payload: Partial<State> | undefined;
};
export type Actions =
| UpdateFiveDayAction
| UpdateLoadingAction;
export interface UpdateLoadingAction extends Action {
type: "UPDATE_LOADING";
payload: { loading: State["loading"] };
}
export interface UpdateFiveDayAction extends Action {
type: "UPDATE_FIVE_DAY";
payload: {
fiveDayForecast: State["fiveDayForecast"];
fiveDayExpiresAt: State["fiveDayExpiresAt"];
fiveDayLocationFor: State["fiveDayLocationFor"];
};
}
相关文章