#javascript #typescript #generics #typescript-typings
#javascript #typescript #общие #typescript-типизации
Вопрос:
Я пытаюсь создать сокращенный тип для своих действий, которые работают с AsyncActionCreators
объектами.
Я создал простую функцию, которая принимает dispatch: Dispatch<T>
параметр React:
const fetchProfileAction = actionCreator.async<void, Profile, any>('FETCH_PROFILE');
// AsyncActionCreators<Params = void, Result = Profile, Error = any>;
type AsyncDispatch<A extends AsyncActionCreators<Params, Result, Error>, Params, Result, Error> = Dispatch<
ReturnType<A['started'] | A['done'] | A['failed']>
>;
export const fetchProfile = (
dispatch: AsyncDispatch<typeof fetchProfileAction, void, Profile, any>,
) => async () => {
dispatch(fetchProfileAction.started());
try {
dispatch(fetchProfileAction.done({ result: (await api.get<Profile>('/profile')).data }));
} catch (e) {
dispatch(fetchProfileAction.failed(e));
}
};
Проблема на данный момент заключается в том, что мне приходится вручную указывать типы, используемые внутри fetchProfileAction
:
AsyncDispatch<typeof fetchProfileAction, void, Profile, any>
Можно ли упростить это и получить что-то вроде AsyncDispatch<typeof fetchProfileAction>
с автоматически разрешенными Params
, Result
, Error
типами AsyncActionCreators
?
Комментарии:
1. Не проверял это, но вы можете попробовать использовать условные типы (извините за форматирование в комментариях):
type AsyncDispatch<A> = A extends AsyncActionCreators<infer Params, infer Result, infer Error> ? Dispatch<ReturnType<A['started'] | A['done'] | A['failed']>> : never;
2. @AlekseyL.
infer
получилось! Если вы опубликуете это как aswer, я приму это.
Ответ №1:
Вы могли бы использовать вывод типа в условных типах:
type AsyncDispatch<A> = A extends AsyncActionCreators<infer Params, infer Result, infer Error>
? Dispatch<ReturnType<A['started'] | A['done'] | A['failed']>>
: never;