Add support for error actions

This commit is contained in:
Jerko Steiner 2019-01-19 17:39:54 +01:00
parent c1d21350a8
commit c1c7c829e7
4 changed files with 32 additions and 11 deletions

View File

@ -3,14 +3,23 @@
// section: Type inference in conditional types // section: Type inference in conditional types
type Unpacked<T> = T extends Promise<infer U> ? U : T type Unpacked<T> = T extends Promise<infer U> ? U : T
import {IAction} from './IAction' import {IAction} from './IAction'
import {IErrorAction} from './IErrorAction'
// Also from TypeScript handbook: // Also from TypeScript handbook:
// https://www.typescriptlang.org/docs/handbook/advanced-types.html // https://www.typescriptlang.org/docs/handbook/advanced-types.html
type FunctionProperties<T> = { type FunctionProperties<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => IAction<any, string> ? { [K in keyof T]:
T[K] extends (...args: any[]) => IAction<any, string>
? {
payload: Unpacked<ReturnType<T[K]>['payload']>, payload: Unpacked<ReturnType<T[K]>['payload']>,
type: Unpacked<ReturnType<T[K]>['type']>, type: Unpacked<ReturnType<T[K]>['type']>,
}: never }
: T[K] extends (...args: any[]) => IErrorAction<string>
? {
error: Error,
type: Unpacked<ReturnType<T[K]>['type']>,
}
: never
} }
// https://stackoverflow.com/questions/48305190/ // https://stackoverflow.com/questions/48305190/

View File

@ -0,0 +1,4 @@
export interface IErrorAction<ActionType extends string> {
error: Error,
type: ActionType
}

View File

@ -1,22 +1,19 @@
import {ActionTypes} from './ActionTypes' import {ActionTypes} from './ActionTypes'
import {IAPIDef, ICredentials, IUser} from '@rondo/common' import {IAPIDef, ICredentials, IUser} from '@rondo/common'
import {IAction} from './IAction'
import {IErrorAction} from './IErrorAction'
import {IHTTPClient} from '../http/IHTTPClient' import {IHTTPClient} from '../http/IHTTPClient'
export enum UserActionKeys { export enum UserActionKeys {
USER_LOG_IN = 'USER_LOG_IN', USER_LOG_IN = 'USER_LOG_IN',
USER_LOG_IN_FULFILLED = 'USER_LOG_IN_FULFILLED', USER_LOG_IN_PENDING = 'USER_LOG_IN_PENDING',
USER_LOG_IN_REJECTED = 'USER_LOG_IN_REJECTED', USER_LOG_IN_REJECTED = 'USER_LOG_IN_REJECTED',
USER_LOG_OUT = 'USER_LOG_OUT', USER_LOG_OUT = 'USER_LOG_OUT',
USER_LOG_OUT_FULFILLED = 'USER_LOG_OUT_FULFILLED', USER_LOG_OUT_PENDING = 'USER_LOG_OUT_PENDING',
USER_LOG_OUT_REJECTED = 'USER_LOG_OUT_REJECTED', USER_LOG_OUT_REJECTED = 'USER_LOG_OUT_REJECTED',
} }
interface IAction<PayloadType, ActionType> {
payload: Promise<PayloadType> | PayloadType,
type: ActionType
}
export class UserActions { export class UserActions {
constructor(protected readonly http: IHTTPClient<IAPIDef>) {} constructor(protected readonly http: IHTTPClient<IAPIDef>) {}
@ -27,6 +24,13 @@ export class UserActions {
} }
} }
logInError(error: Error): IErrorAction<UserActionKeys.USER_LOG_IN_REJECTED> {
return {
error,
type: UserActionKeys.USER_LOG_IN_REJECTED,
}
}
logOut(): IAction<unknown, UserActionKeys.USER_LOG_OUT> { logOut(): IAction<unknown, UserActionKeys.USER_LOG_OUT> {
return { return {
payload: this.http.get('/auth/logout'), payload: this.http.get('/auth/logout'),

View File

@ -2,18 +2,22 @@ import {IUser} from '@rondo/common'
import {UserActionKeys, UserActionType} from '../actions/UserActions' import {UserActionKeys, UserActionType} from '../actions/UserActions'
interface IState { interface IState {
error?: string,
user?: IUser user?: IUser
} }
const defaultState: IState = { const defaultState: IState = {
error: undefined,
user: undefined, user: undefined,
} }
export function user(state = defaultState, action: UserActionType): IState { export function user(state = defaultState, action: UserActionType): IState {
switch (action.type) { switch (action.type) {
case UserActionKeys.USER_LOG_IN: case UserActionKeys.USER_LOG_IN:
return {user: action.payload} return {...state, user: action.payload}
case UserActionKeys.USER_LOG_OUT: case UserActionKeys.USER_LOG_OUT:
return {user: undefined} return {...state, user: undefined}
case UserActionKeys.USER_LOG_IN_REJECTED:
return {...state, error: action.error.message}
} }
} }