当我们在typescript的项目中使用dva的时候,models内的effect写法,要怎么写才能做到尽量的优雅+规范呢?比如这里有一个userModel.ts,里面的effect为:
*login({ payload, callback }, { put }) {
// code here...
},
假如我们的项目使用了eslint插件,这时候我们会得到错误提示,绑定元素“payload”隐式具有“any”类型。ts(7031)
,因为我们没有参考类型,那这里我们要如何书写相关参数的参考类型呢?payload里面的内容,我们无法确定。所以目前只能使用any,也就是:
*login({ payload, callback } : any, { put }:any) {
// code here...
},
有没有更好的写法呢?谢谢!
请使用
yarn create umi
创建,选择app
,然后选上dva
,并上传到你的 GitHub 仓库
无
无
这样不知道能不能达到你想要的效果
import { Model } from 'dva';
export default {
name: 'test',
state: {},
effects: {},
} as Model;
What happens?
当我们在typescript的项目中使用dva的时候,models内的effect写法,要怎么写才能做到尽量的优雅+规范呢?比如这里有一个userModel.ts,里面的effect为:
*login({ payload, callback }, { put }) { // code here... },
假如我们的项目使用了eslint插件,这时候我们会得到错误提示,
绑定元素“payload”隐式具有“any”类型。ts(7031)
,因为我们没有参考类型,那这里我们要如何书写相关参数的参考类型呢?payload里面的内容,我们无法确定。所以目前只能使用any,也就是:*login({ payload, callback } : any, { put }:any) { // code here... },
有没有更好的写法呢?谢谢!
最小可复现仓库
请使用
yarn create umi
创建,选择app
,然后选上dva
,并上传到你的 GitHub 仓库无
复现步骤,错误日志以及相关配置
无
相关环境信息
- Umi 版本:未使用
- Node 版本:11.2.0
- 操作系统:macOS 10.14.5
你可以试试看我写的库
https://github.com/DiamondYuan/dva-model-creator
可以做到每一个 action 每一个 model 的类型都是完备的。而且和现有的 dva 完全兼容。
我已经用在生产环境了。
demo 地址
https://github.com/umijs/umi-examples/tree/master/typescript
@jinyang1994 我这边使用的时dva-core和dva-loading,没有使用dva全套,这样的话应该如何
import { Model } from 'dva';
再者想了解一下,这个as Model的用意是什么?谢谢。
as是类型断言
dva-core 不行的话可以只用dva的types
@jinyang1994
我从dva的声明文件index.d.ts和issue中一些相关问题中参考抽取出来了一个Model.ts作为一个类型,在models中使用,具体如下:
/* eslint-disable no-unused-vars */
import { ReducersMapObject, Reducer, Dispatch, AnyAction, Action } from 'redux';
export interface EffectsCommandMap {
put: <A extends Action>(action: A) => any;
call: Function;
select: Function;
take: Function;
cancel: Function;
[key: string]: any;
}
export interface EffectsMapObject {
[key: string]: Effect | EffectWithType;
}
export interface ReducerEnhancer {
(reducer: Reducer<any>): void;
[key: string]: Reducer;
}
export interface SubscriptionAPI {
dispatch: Dispatch<any>;
}
// export type ActionWithPayload = { action: Action; payload: any };
export type Effect = (action: AnyAction, effects: EffectsCommandMap) => void;
export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
export type EffectWithType = [Effect, { type: EffectType }];
export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];
export type Subscription = (api: SubscriptionAPI, done: Function) => void;
export interface SubscriptionsMapObject {
[key: string]: Subscription;
}
export default interface Model {
namespace: string;
state?: any;
reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
effects?: EffectsMapObject;
subscriptions?: SubscriptionsMapObject;
}
配合断言(as Model),现在effects中的相关类型都已正确解析,唯独reducers中的传递的payload参数仍然无法解析,编辑器vscode报错为:类型“Action
import Model from '@/utils/dva/Model';
export default {
namespace: 'userModel',
state: {
status: 'logout',
currentUser: '',
},
effects: {
*login({ payload, callback }, { put }) {
// ...
},
},
reducers: {
//这里的payload类型判断失败,报错为类型“Action<any>”上不存在属性“payload”。
changeLoginStatus(state, { payload }) {
return {
...state,
// ....
};
},
},
} as Model;
请问这边哪里做的还有问题?谢谢!
用这个吧 dva-model-creator
这个redux框架完美支持ts,拥有100%的代码提示: redux-model-ts
感谢楼上各位老哥的推荐,但是作为一个ts初学者还是想尽量自己手撸。经过我后期的实践,发现像我之前的解决方案摘出dva的Model,然后配合断言是可以实现的。唯一的问题是,在Redux升级到V4后,他的ReducersMapObject做了改变,所以我从Redux V3里面找到了相关的源代码对Model进行了改造,实测好用,分享给有缘人:
/* eslint-disable no-unused-vars */
import { ReducersMapObject, Reducer, Dispatch, AnyAction, Action } from 'redux';
export interface EffectsCommandMap {
put: <A extends Action>(action: A) => any;
call: Function;
select: Function;
take: Function;
cancel: Function;
[key: string]: any;
}
// export type ActionWithPayload = { action: Action; payload: any; callback: Function };
export type Effect = (action: AnyAction, effects: EffectsCommandMap) => void;
export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
export type EffectWithType = [Effect, { type: EffectType }];
export interface EffectsMapObject {
[key: string]: Effect | EffectWithType;
}
export interface ReducerEnhancer {
(reducer: Reducer<any>): void;
}
// 使用redux-v4.x的ReducerMapObject会导致dva reducer中的action payload等参数无法确定类型(dva中使用的是3.x的redux)
// 这里从redux v3.x中找到了对应的ReducersMapObject以解决上述问题
export interface ReduxV3ReducersMapObject {
[key: string]: Reducer<any>;
}
export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];
export interface SubscriptionAPI {
dispatch: Dispatch<any>;
}
export type Subscription = (api: SubscriptionAPI, done: Function) => void;
export interface SubscriptionsMapObject {
[key: string]: Subscription;
}
export default interface Model {
namespace: string;
state?: any;
// reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
reducers?: ReduxV3ReducersMapObject | ReducersMapObjectWithEnhancer;
effects?: EffectsMapObject;
subscriptions?: SubscriptionsMapObject;
}
谢谢老哥,我也是ts初学者,学到不少
Most helpful comment
感谢楼上各位老哥的推荐,但是作为一个ts初学者还是想尽量自己手撸。经过我后期的实践,发现像我之前的解决方案摘出dva的Model,然后配合断言是可以实现的。唯一的问题是,在Redux升级到V4后,他的ReducersMapObject做了改变,所以我从Redux V3里面找到了相关的源代码对Model进行了改造,实测好用,分享给有缘人: