Мой исходный код выглядит следующим образом. Он позволяет мне определять тип данных на основе типа при переключении на действие:ActionType.
enum Actions {
GET_MESSAGES,
GET_MESSAGES_LOADED
}
//@ts-ignore
const AppActions = {
getMessages() {
return {
type: Actions.GET_MESSAGES,
data:{id: 1}
};
},
getMessagesLoaded() {
return {
type: Actions.GET_MESSAGES_LOADED,
data:{messages: ['asdf']}
};
}
};
type ActionType = ReturnType<typeof AppActions[keyof typeof AppActions]>;
const func = (action:ActionType) => {
// @ts-ignore
switch (action.type) {
case Actions.GET_MESSAGES:
console.log(action.data.id) //Should pass
break
case Actions.GET_MESSAGES_LOADED:
console.log(action.data.messages) //Should pass
break;
case Actions.GET_MESSAGES_ERROR: // Should throw typescript error
// default:
// break;
}
};
Я хотел бы знать, могу ли я создать объединение ActionType динамически, сопоставляя ключи AppActions?
Самый близкий ответ
Ответ @Elias на данный момент type ActionType = ReturnType<typeof AppActions[keyof typeof AppActions]>;
вырезает здесь большую часть наворотов.
Вышеприведенное работает отлично, пока каждая функция в AppActions имеет указанный тип возвращаемого значения, без этого тип данных не может быть обнаружен, однако он правильно определяет Actions.GET_MESSAGES_ERROR является недопустимым действием.type.
Решит ли это для вас
type ReturnTypeOfKeysOfUnion<T> = T extends T ? ReturnType<typeof AppActions[T]> : never;
?@RazLuvaton Как это работает? Если вы посмотрите на мое решение, его действительно легко понять по сравнению с этим. Я не говорю, что у вас плохо, я искренне заинтересован.
@Elias Это решение работает с тем фактом, что условные типы поверх общих союзов становятся дистрибутивными: typescriptlang.org/docs/handbook/2/…
Мне нравится ваш уважительный комментарий!
Похоже, это выше моей головы... @IngoBürk, но спасибо за ссылку на документ!
@RazLuvaton Я не уверен, почему, но он сообщает об ошибке для меня :( stackblitz.com/edit/typescript-c7emdb?file=index.ts
Попробуйте вместо этого -
type ReturnTypeOfKeysOfUnion<T> = T extends keyof typeof AppActions ? ReturnType<typeof AppActions[T]> : never;
Первый написанный мной тип я не проверял (писал на телефон 😉)
@RazLuvaton Как его инициализировать?
let m: ReturnTypeOfKeysOfUnion = AppActions.getMessagesLoaded();
не будет работать из-за отсутствия аргумента типа. Это особенно важно, поскольку мой ответ кажется недействительным. coderhelper.com/questions/68703207/…Я вижу, что это не работает, у меня нет идей 🤷🏻♂️
@RazLuvaton Честно говоря, это мой «ответ наизусть», но на самом деле это не ответ на вопрос coderhelper.com/questions/68703207/…