Last active
October 24, 2018 03:38
-
-
Save JonasGao/3341e53456e2060fc1538aabf38ccef2 to your computer and use it in GitHub Desktop.
make better type for dva
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Action, AnyAction } from "redux" | |
type creator = (payload?: any, withNamespace?: boolean) => Action | |
type Creators<T> = { | |
[P in keyof T]: creator | |
}; | |
interface Model<S, E, R> { | |
namespace: string, | |
state: S, | |
effects?: E, | |
reducers: R, | |
} | |
interface ModelWrap<S, E, R> { | |
model: Model<S, E, R>, | |
creators: { | |
effects: Creators<E>, | |
reducers: Creators<R>, | |
} | |
} | |
function _creators<T>(obj: T, namespace: string): Creators<T> { | |
return Object.keys(obj).reduce((obj, key) => { | |
obj[ key ] = function (payload = {} as any, withNamespace) { | |
payload.type = withNamespace ? `${namespace}/${key}` : key | |
return payload | |
} | |
return obj | |
}, {}) as Creators<T> | |
} | |
export interface DvaEffectCreators { | |
takeEvery: Function, | |
takeLatest: Function, | |
throttle: Function, | |
take: Function, | |
put: Function, | |
call: Function, | |
fork: Function, | |
spawn: Function, | |
join: Function, | |
cancel: Function, | |
select: Function, | |
actionChannel: Function, | |
flush: Function, | |
cancelled: Function, | |
race: Function, | |
all: Function, | |
} | |
export interface IDvaEffect<A = AnyAction> { | |
(action: A, effects: DvaEffectCreators): IterableIterator<any> | |
} | |
export interface IDvaWatchEffect { | |
(effects: DvaEffectCreators): void | |
} | |
export interface IDvaReducer<S, A = AnyAction> { | |
(state: S, action: A): void | |
} | |
export interface IDvaEffects { | |
[ extraProps: string ]: IDvaEffect | [ IDvaEffect | IDvaWatchEffect, any ]; | |
} | |
export interface IDvaReducers<S> { | |
[ extraProps: string ]: IDvaReducer<S>; | |
} | |
export function createModel<S extends object, | |
E extends IDvaEffects, | |
R extends IDvaReducers<S>, | |
SS = {}>( | |
namespace: string, | |
state: S, | |
effects: E, | |
reducers: R, | |
subscriptions?: SS, | |
): ModelWrap<S, E, R> { | |
const model = { | |
namespace, | |
state, | |
effects, | |
reducers, | |
subscriptions | |
} | |
return { | |
model, | |
creators: { | |
effects: _creators(effects, namespace), | |
reducers: _creators(reducers, namespace), | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { model, creators: { effects, reducers } } = createModel( | |
"demo", // namespace | |
{ | |
msg: null, | |
}, // state | |
{ | |
* fetch(action, { put }) { | |
yield put(reducers.updateMsg({ msg: "Hello, World" })) | |
}, | |
}, // effects | |
{ | |
updateMsg(state, { msg }) { | |
// please use dva-immer plugin | |
state.msg = msg | |
} | |
} // reducers | |
) | |
export default model | |
// action creator for component or other model | |
export function fetch() { | |
return effects.fetch({}, true) // if true, creator will auto prefix namespace | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment