@perfylee/dva-model
Version:
dva model create tool
148 lines (132 loc) • 3.52 kB
text/typescript
interface AnyAction {
type: any;
[key: string]: any;
}
interface Action<TPayload = any> extends AnyAction {
type: string;
payload?: TPayload;
callback?: Function;
}
interface EffectsCommandMap {
put: <A extends AnyAction>(action: A) => any;
call: Function;
select: Function;
take: Function;
cancel: Function;
[key: string]: any;
}
declare type Effect<TPayload = any> = (
action: {
payload: TPayload,
callback?: Function;
},
effects: EffectsCommandMap,
) => void
declare type Reducer<TState = any, TPayload = any> = (
state: TState,
action: {
payload: TPayload,
},
) => TState
interface GlobalState<TState> {
loading: {
global: boolean;
effects: { [key: string]: boolean | undefined };
models: {
[key: string]: any;
};
};
[key: string]: TState | any;
}
interface Model<TState = any> {
namespace: string;
state?: TState;
reducers: {
[key: string]: Reducer
};
effects: {
[key: string]: Effect
}
subscriptions?: any;
/**
* 创建reducer
*/
reducer: <TPayload>(action: ActionCreator<TPayload>, reducer: Reducer<TState, TPayload>) => Model<TState>
/**
* 创建effect
*/
effect: <TPayload>(action: ActionCreator<TPayload>, effect: Effect<TPayload>) => Model<TState>
/**
* State选择器,配合dva的useSelector使用
*/
selector: (state: GlobalState<TState>) => TState & { loading: { [key: string]: boolean | undefined } }
}
/**
* Action创建
*/
declare type ActionCreator<TPayload = any> = {
/**
* Action创建方法
* @param payload 参数负载
* @param callback 回调函数
*/
(payload?: TPayload, callback?: Function): Action<TPayload>;
/**
* action type
* 含model命名空间的完整type
*/
type: string;
/**
* action type
* 不含model命名空间的type
*/
originType: string;
}
/**
* Action创建工厂
* @param namespace model命名空间
*/
export function actionCreatorFactory(namespace: string) {
return <TPayload = any>(type: string): ActionCreator<TPayload> => {
const fullType = `${namespace}/${type}`
const actionCreator = (payload?: TPayload, callback?: Function) => {
return {
type: fullType,
payload,
callback
}
}
actionCreator.type = fullType
actionCreator.originType = type
return actionCreator
}
}
/**
* Model创建方法
* @param namespace 命名空间
* @param initState 初始State
* @returns
*/
export function createModel<TState>(namespace: string, initState: TState): Model<TState> {
const model: Model<TState> = {
namespace,
state: initState,
reducers: {},
effects: {},
reducer: (action, reducer) => {
model.reducers[action.originType] = reducer
return model
},
effect: (action, effect) => {
model.effects[action.originType] = effect
return model
},
selector: (state: GlobalState<TState>) => {
return {
...state[namespace],
loading: state.loading.effects
}
}
}
return model
}