有这么一个action,我想限制payload的类型为IGetPagePayload
const systemModule: Module<ISystemState, IRootState> = {
namespaced: true,
......
actions: {
getPageListAction({ commit }, payload: IGetPagePayload) {
console.log(payload);
}
}
};
以下是IGetPagePayload的类型定义
export interface IQueryInfo {
offset: number;
size: number;
}
export interface IGetPagePayload {
pageUrl: string;
queryInfo?: IQueryInfo;
}
现在我要在某个地方通过store.dispatch,调用上面的getPageListAction方法并期望dispatch中第二个对象参数payload的类型被限制为IGetPagePayload,所以编写如下代码。
store.dispatch("system/getPageListAction", {
pageUrl: "/user/list",
queryInfo: {
offset: 0,
size: 10
}
});
但查看queryInfo的类型,发现并不是所期望的IQueryInfo,而是自推导的 {offset:number;size:number;} 类型,说明payload的类型并没有得到限制。
查看源码中dispatch方法的类型定义,发现它的类型是Dispatch(定义如下)
dispatch: Dispatch;
export interface Dispatch {
(type: string, payload?: any, options?: DispatchOptions): Promise<any>;
<P extends Payload>(payloadWithType: P, options?: DispatchOptions): Promise<any>;
}
可以看出dispatch方法有两种传递参数的方式,第一种分别接收
- type:string
- payload?:any
- options?:DispatchOptions
以上三个参数,其中payload类型为any,显然没有任何方法能在此处做类型限制,所以考虑第二种传参方式
-
接收一个泛型P继承自接口Payload
-
payloadWithType: P
-
options?: DispatchOptions
看一下Payload的接口定义
export interface Payload {
type: string;
}
也就是说,第二种传参方式需要接收一个含有type属性的泛型,并且会把该泛型赋给第一个参数payloadWithType,不难看出此处便可以通过构造一个含有type,并且包含原所需数据类型的接口来实现我们对payload的类型限制。
因此,修改接口IGetPagePayload将type属性纳入其中,随后修改dispatch的调用方法以泛型方式传入该类型。
export interface IGetPagePayload {
type: string;
pageUrl: string;
queryInfo?: IQueryInfo;
}
store.dispatch<IGetPagePayload>({
type: "system/getPageListAction",
pageUrl: "/user/list",
queryInfo: {
offset: 0,
size: 10
}
});
再次查看queryInfo的类型,可以看到此处已被限制为IQueryInfo | undefined的可选类型,至此,对dispatch中payload的类型限制问题解决。