#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];
Должен делать то, что вы хотите.
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