Повторное использование общих типов расширенного интерфейса при создании сокращенного типа

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