Skip to content

Instantly share code, notes, and snippets.

@pridees
Created June 5, 2021 14:26
Show Gist options
  • Save pridees/39f40c5f475085943cdb8b6f4f3eca21 to your computer and use it in GitHub Desktop.
Save pridees/39f40c5f475085943cdb8b6f4f3eca21 to your computer and use it in GitHub Desktop.
// REDUX
// Action
type Action<T = any> = {
actionType: T
}
type AnyAction<Payload = any> = Action & {
payload: Payload
}
type ActionMethod<Payload, ActionType = any> = (payload: Payload, actionType?: ActionType) => AnyAction<Payload>
// Reducer
type Reducer<S, A = AnyAction> = (state: S, action: A) => S
type CombinedState<RootState extends Object> = {
[StateKey in keyof RootState]: RootState[StateKey]
}
type CombinedReducers<
RootState extends Object,
A extends Action = AnyAction
> = {
[StateKey in keyof RootState]: Reducer<RootState[StateKey], A>
}
// Store
class Store<RootState> {
private state: CombinedState<RootState>
private reducers: CombinedReducers<RootState>
constructor(state: RootState, reducers: CombinedReducers<RootState>) {
this.state = state
this.reducers = reducers;
}
reduce(action: AnyAction) {
this.printState()
console.log(`DEBUG: ${action.actionType}`, action)
const stateKeys = Object.keys(this.state) as Array<keyof RootState>
stateKeys.forEach(stateKey => {
this.state[stateKey] = this.reducers[stateKey](this.state[stateKey], action)
})
}
printState() {
console.log("--------- current state start----------")
console.log(this.state)
console.log("--------- current state end ----------")
}
}
// Dispatch
type Dispatch<Payload = any> = (action: AnyAction<Payload>) => void
function dispatchWrapper<RootState>(store: Store<RootState>): Dispatch {
return (action: AnyAction) => void store.reduce(action)
}
/* implement reducer */
type AuthState = {
isAuth: boolean
}
enum AuthActionTypes {
SET_AUTH = 'AUTH.SET_USER_AUTH'
}
type AuthPayloadDTO = {
authResult: boolean
}
const setAuthResult: ActionMethod<AuthPayloadDTO, AuthActionTypes>
= (payload, actionType = AuthActionTypes.SET_AUTH) => ({
actionType,
payload,
})
const initialAuthState: AuthState = {
isAuth: false
}
const authReducer: Reducer<AuthState> = (state, action): AuthState => {
switch (action.actionType) {
case AuthActionTypes.SET_AUTH:
return {
...state,
isAuth: action.payload.authResult
}
default:
return state;
}
}
/* implement store */
type RootState = {
authState: AuthState
}
const rootState: RootState = {
authState: initialAuthState
}
const combinedReducers: CombinedReducers<RootState> = {
authState: authReducer
}
const rootStore = new Store<RootState>(rootState, combinedReducers)
const dispatch = dispatchWrapper(rootStore)
dispatch(setAuthResult({ authResult: true }))
rootStore.printState()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment