Typescript преобразует тип редукторов в действия

#typescript

#typescript

Вопрос:

У меня есть ссылка на объект:

 const reducers = {
  increment: (state: State, payload: number) => {
    return { count: state.count   payload };
  },
  decrement: (state: State, payload: number) => {
    return { count: state.count - payload };
  },
  console: (state: State, payload: string) => {
    console.log(payload);
    return { count: state.count };
  },
};
  

если я хочу получить тип, подобный этому:

 type reducerType =
  | { type: 'increment'; payload: number }
  | { type: 'decrement'; payload: number }
  | { type: 'console'; payload: string };
  

Как я должен преобразовать его так же, как Exclud или Pick ?

Ответ №1:

Сначала давайте извлекем тип из вашего const с помощью

 type Reducer = typeof reducers;
  

Затем получаем тип полезной нагрузки

 type ExtractPayload<T> = T extends (arg1: any, payload: infer U) => any ? U : never;
  

Еще один инструмент, который нам понадобится, — это тип для редуктора

 type ToReducerType<K extends KeyT, T> = { "type": K, payload: T };
  

(забудьте о KeyT на данный момент)
Теперь у нас есть все, чтобы определить наш тип, чтобы

 type ToReducersType<T> = { [P in keyof T]: ToReducerType<P, ExtractPayload<T[P]>> }[keyof T];
  

Должен делать то, что вы хотите.

Вот весь пример {
return { count: state.count + payload };
},
decrement: (state: State, payload: number) => {
return { count: state.count — payload };
},
console: (state: State, payload: string) => {
console.log(payload);
return { count: state.count };
},
};

type KeyT = string | number | symbol;

type Reducer = typeof reducers;

type ExtractPayload = T extends (arg1: any, payload: infer U) => any ? U : never;

type ToReducerType = { «type»: K, payload: T };

type ToReducersType = { [P in keyof T]: ToReducerType<P, ExtractPayload> }[keyof T];

type ReducerTypes = ToReducersType;

const a: ReducerTypes = {
«type»: «decrement»,
payload: 6
}» rel=»nofollow noreferrer»>tsplayground