我具有以下类型的并集:
export interface GetAll { type: PeopleActionTypes.GET_ALL; }
export type GetAllOk = ApiActionCreator<{ type: PeopleActionTypes.GET_ALL_OK; }>;
export type GetAllFail = ApiActionCreator<{type: PeopleActionTypes.GET_ALL_FAIL}>;
export type GetOne = ApiActionCreator<{type: PeopleActionTypes.GET_ONE}>;
export type GetOneOk = ApiActionCreator<{type: PeopleActionTypes.GET_ONE_OK}>;
export type GetOneFail = ApiActionCreator<{type: PeopleActionTypes.GET_ONE_FAIL}>;
export type Add = ApiActionCreator<{type: PeopleActionTypes.ADD}, Fetchable<Person>>;
export type AddOK = ApiActionCreator<{type: PeopleActionTypes.ADD_OK}, Fetchable<Person>[]>;
export type AddFail = ApiActionCreator<{type: PeopleActionTypes.ADD_FAIL}>;
export type Update = ApiActionCreator<{type: PeopleActionTypes.UPDATE}>;
export type UpdateOK = ApiActionCreator<{type: PeopleActionTypes.UPDATE_OK}, Fetchable<Person>[]>;
export type UpdateFail = ApiActionCreator<{type: PeopleActionTypes.UPDATE_FAIL}>;
export type Remove = ApiActionCreator<{type: PeopleActionTypes.REMOVE}>;
export type RemoveOK = ApiActionCreator<{type: PeopleActionTypes.REMOVE_OK}>;
export type RemoveFail = ApiActionCreator<{type: PeopleActionTypes.REMOVE_FAIL}>;
export type ResetPassword = ApiActionCreator<{type: PeopleActionTypes.RESET_PASSWORD}>;
export type ResetPasswordOK = ApiActionCreator<{type: PeopleActionTypes.RESET_PASSWORD_OK}>;
export type ResetPasswordFail = ApiActionCreator<{type: PeopleActionTypes.RESET_PASSWORD_FAIL}>;
export interface SetCurrent {
type: PeopleActionTypes.SET_CURRENT;
id: string;
};
export type PeopleActionCreators =
SetCurrent
| GetAll
| GetAllOk
| GetAllFail
| GetOne
| GetOneOk
| GetOneFail
| Add
| AddOK
| AddFail
| Update
| UpdateOK
| UpdateFail
| Remove
| RemoveOK
| RemoveFail
| ResetPassword
| ResetPasswordOK
| ResetPasswordFail;
我的ApiActionCreator
如下所示:
export type ApiActionCreator<T extends object, Payload = object | any[] | undefined> = T & { payload: Payload, error: ErrorMessage }
对于每个操作,我都有一个Xxx
,XxxOK
和一个XxxFail
。
无论如何,打字稿中是否仍可以某种方式生成这些类型,而不必为所有操作创建全部3种?
答案 0 :(得分:1)
您可以避免通过使用有条件的,有条件的类型(包含在包含联合的类型参数上)来声明所有联合。使用这种行为,我们可以将ApiActionCreator
应用于枚举文字联合的所有成员。
我们可以使用PeopleActionTypes
条件类型(SET_CURRENT
)来获取Exclude
中不包括type PeopleActionTypesKeys = Exclude<PeopleActionTypes, PeopleActionTypes.SET_CURRENT>
的所有文字枚举的并集,以不同的方式对其进行处理
唯一存在的问题是某些操作类型的自定义有效负载。我们可以将对象类型用作映射,以保持枚举成员与有效负载类型之间的关系。
type GetPayload<TPayloadMap, T extends PropertyKey> = TPayloadMap extends Record<T, infer U> ? U : undefined;
export type StandardActions<TEnumKeys, TPayloadMap> =
TEnumKeys extends any ? ApiActionCreator<{type: TEnumKeys }, GetPayload<TPayloadMap, TEnumKeys>>
: never ;
export interface SetCurrent {
type: PeopleActionTypes.SET_CURRENT;
id: string;
};
type PeopleActionTypesKeys = Exclude<PeopleActionTypes, PeopleActionTypes.SET_CURRENT>
export type PeopleActionCreators = SetCurrent | StandardActions<PeopleActionTypesKeys, {
[PeopleActionTypes.ADD]: Fetchable<Person>,
[PeopleActionTypes.UPDATE]: Fetchable<Person>,
[PeopleActionTypes.ADD_OK]: Fetchable<Person>,
}>;
上述解决方案的重复次数较少,不幸的是,如果将鼠标悬停在PeopleActionCreators
上,则会丢失类型别名的漂亮名称。
type PeopleActionCreators = SetCurrent | ApiActionCreator<{
type: PeopleActionTypes.GET_ALL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.GET_ALL_OK;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.GET_ALL_FAIL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.GET_ONE;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.GET_ONE_OK;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.GET_ONE_FAIL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.ADD;
}, Fetchable<Person>> | ApiActionCreator<{
type: PeopleActionTypes.ADD_OK;
}, Fetchable<Person>> | ApiActionCreator<{
type: PeopleActionTypes.ADD_FAIL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.UPDATE;
}, Fetchable<Person>> | ApiActionCreator<{
type: PeopleActionTypes.UPDATE_OK;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.UPDATE_FAIL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.REMOVE;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.REMOVE_OK;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.REMOVE_FAIL;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.RESET_PASSWORD;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.RESET_PASSWORD_OK;
}, undefined> | ApiActionCreator<{
type: PeopleActionTypes.RESET_PASSWORD_FAIL;
}, undefined>
尽管可读性很差,但是可读性却很差,对于其他人来说,代码本身也可能更难以理解。