alova
alova copied to clipboard
[Feature] 在ts项目中,`send`函数参数类型自动推断的讨论
你在什么情况下,需要这个功能解决什么问题?
由 https://github.com/alovajs/alova/issues/103 开头,看如下示例:
const { data, loading, send } = useRequest((query: { q: number }) => doTest(query), {
initialData: "",
immediate: false,
})`
// 目前send类型是(...args: any[]) => Promise<...>,期望得到准确的提示:({q:number})=>Prmise<...>
而我一开始的想法是,如果说send
函数的参数类型按useRequest
的回调函数参数类型来自动推断的话,这个是可以做到的,只是从设计层面上来说,send
函数的参数不止会被传入useRequest
的回调函数,这些参数还会被传到onSuccess
、onError
、onComplete
事件回调中,当force
配置项设置为函数时也还会传给它,还有middleware
也可以接收到,这样的话,就不好界定应该使用哪个类型了。
后来,我的想法有了一点改变,由于使用频率和整体收益来看,让send
函数支持类型也不失为一种更好的方案,目前来说,从设计方案上需要达到send函数自动提示,同时也可以不完全受use hooks的handler限制,因为有些时候会专门需要传参到onSuccess等回调函数中。
你期望的 API 是什么样子的?
我暂时还没有满意的方案,在此,本着共同建设的目的,邀请同样感兴趣的你一起来讨论出一个合适的方案,各抒己见。 不怕说错就怕不说。
目前还处于小白学习阶段,想不出什么好的方案,只是考虑到个人的实际业务:
前端的api文件夹(包含请求地址及接口参数对应的ts类型)是根据后端解析swagger文件自动生成的。 在开发场景中,后端对接口做了调整后,前端对应的接口参数或响应的ts类型也会发生变化,能很方便的知道后端的改动情况(虽然这种情况应该由后端主动做出告知,但emm),小团队开发无测试,暂就依赖ts类型减免bug率。
然后觉得send有ts支持在开发过程中也比较便利,可能也是基本没怎么用过onSuccess、onError这种回调(个人原因吧)才没有深入理解作者的意图。
怎么没有人来啊,推动一下啊55,TS大环境下真的还有人习惯 JS 编程吗
@z91300 可能是参与alova社区活跃的人还不多吧,目前来说缺少这个ts提示应该也不至于到很痛苦的程度,我们需要再一点点的耐心,我也在一同参与思考这个问题,尽量给出更好的优化
怎么没有人来啊,推动一下啊55,TS大环境下真的还有人习惯 JS 编程吗
最新不是有框架推介js编程,不用ts吗。小白觉得ts有时候改一点东西,比js还改多好几个地方。。。
等你再接触多一点项目可能就会发现了吧,以前也挺烦ts的,后来也是慢慢感觉到真香 ,当然js爱好者肯定也还有,但ts依然是主流 @wintsa123
@JOU-amjs 我认为是要 send 函数是要支持 TS 类型推断的,这对开发者确实很友好。但是你说的由于 onSuccess 等回调也接收了参数所以不好界定使用类型,这句话我没有太懂
@changlin2569 就是例如调用send(1, 2, 3)
时,onSuccess(({ sendArgs }) => { /* ... */ })
中的sendArgs就是[1, 2, 3]
,onError/onComplete/force
同理
@JOU-amjs 这样在 onSuccess 回调中透出具体类型有什么弊端吗?
@changlin2569 不是说弊端,而是send
调用参数会分别传到以上的回调中,因此send
函数的类型如果只由use hook的methodHandler
函数决定的话是不够严谨的,因为有时候send
参数会特意为其他回调传递参数。例如以下示例:
const data1 = ref({});
const data2 = ref({});
const { onSuccess, send } = useRequest((v1: string, v2: number) => createMethod(v1, v2));
onSuccess(({ data, sendArgs: [v1, v2, updateType] }) => {
if (updateType === 'one') {
data1.value = data;
} else {
data2.value = data;
}
});
send('a', 0, 'one');
按上面的写法,如果send的参数类型按(v1: string, v2: number) => createMethod(v1, v2)
自动推断,那么send
的传参类型就是string
和number
,但其实在onSuccess
还需要接收第三个参数用于成功回调内,而与methodHandler
无关。这种情况下直接推断就不够友好。
可能会觉得会有其他方式来解决这个问题,但按我在usePagination策略中使用情况看,因为同时需要考虑react/vue/svelte
,这种传参方式才比较合适,因为react的机制是每次变动都会重新执行usePagination
这个hook。
但我在这个issue开头表达过了,这种情况用的比较少,使用methodHandler
的推断类型对开发者的收益是比较大的,所以我其实是倾向于这个方案的,但现在的问题是如何兼容上面这种情况。
将 send 时传的额外参数变成 any
就好了,比如在 send 的参数类型后加个 & Record<string, any>
之类的来兼容额外的参数
@JOU-amjs 可以将send的入参类型和onSuccess的sendArgs类型定义成这样type Arg = [ ...Parameters<typeof request>,...any ]
https://github.com/alovajs/alova/pull/375
我提了一个pr可以看一下能否解决问题
已按各位预期的设计发布,升级到[email protected]可使用