alova icon indicating copy to clipboard operation
alova copied to clipboard

[Feature] 在ts项目中,`send`函数参数类型自动推断的讨论

Open JOU-amjs opened this issue 1 year ago • 11 comments

你在什么情况下,需要这个功能解决什么问题?

由 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的回调函数,这些参数还会被传到onSuccessonErroronComplete事件回调中,当force配置项设置为函数时也还会传给它,还有middleware也可以接收到,这样的话,就不好界定应该使用哪个类型了。

后来,我的想法有了一点改变,由于使用频率和整体收益来看,让send函数支持类型也不失为一种更好的方案,目前来说,从设计方案上需要达到send函数自动提示,同时也可以不完全受use hooks的handler限制,因为有些时候会专门需要传参到onSuccess等回调函数中。

你期望的 API 是什么样子的?

我暂时还没有满意的方案,在此,本着共同建设的目的,邀请同样感兴趣的你一起来讨论出一个合适的方案,各抒己见。 不怕说错就怕不说。

JOU-amjs avatar Jul 18 '23 09:07 JOU-amjs

目前还处于小白学习阶段,想不出什么好的方案,只是考虑到个人的实际业务:

前端的api文件夹(包含请求地址及接口参数对应的ts类型)是根据后端解析swagger文件自动生成的。 在开发场景中,后端对接口做了调整后,前端对应的接口参数或响应的ts类型也会发生变化,能很方便的知道后端的改动情况(虽然这种情况应该由后端主动做出告知,但emm),小团队开发无测试,暂就依赖ts类型减免bug率。

然后觉得send有ts支持在开发过程中也比较便利,可能也是基本没怎么用过onSuccess、onError这种回调(个人原因吧)才没有深入理解作者的意图。

z91300 avatar Jul 18 '23 09:07 z91300

怎么没有人来啊,推动一下啊55,TS大环境下真的还有人习惯 JS 编程吗

z91300 avatar Jul 20 '23 09:07 z91300

@z91300 可能是参与alova社区活跃的人还不多吧,目前来说缺少这个ts提示应该也不至于到很痛苦的程度,我们需要再一点点的耐心,我也在一同参与思考这个问题,尽量给出更好的优化

JOU-amjs avatar Jul 21 '23 08:07 JOU-amjs

怎么没有人来啊,推动一下啊55,TS大环境下真的还有人习惯 JS 编程吗

最新不是有框架推介js编程,不用ts吗。小白觉得ts有时候改一点东西,比js还改多好几个地方。。。

wintsa123 avatar Jul 24 '23 08:07 wintsa123

等你再接触多一点项目可能就会发现了吧,以前也挺烦ts的,后来也是慢慢感觉到真香 ,当然js爱好者肯定也还有,但ts依然是主流 @wintsa123

z91300 avatar Jul 26 '23 04:07 z91300

@JOU-amjs 我认为是要 send 函数是要支持 TS 类型推断的,这对开发者确实很友好。但是你说的由于 onSuccess 等回调也接收了参数所以不好界定使用类型,这句话我没有太懂

changlin2569 avatar Aug 10 '23 08:08 changlin2569

@changlin2569 就是例如调用send(1, 2, 3)时,onSuccess(({ sendArgs }) => { /* ... */ })中的sendArgs就是[1, 2, 3]onError/onComplete/force同理

JOU-amjs avatar Aug 10 '23 11:08 JOU-amjs

@JOU-amjs 这样在 onSuccess 回调中透出具体类型有什么弊端吗?

changlin2569 avatar Aug 11 '23 02:08 changlin2569

@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的传参类型就是stringnumber,但其实在onSuccess还需要接收第三个参数用于成功回调内,而与methodHandler无关。这种情况下直接推断就不够友好。

可能会觉得会有其他方式来解决这个问题,但按我在usePagination策略中使用情况看,因为同时需要考虑react/vue/svelte,这种传参方式才比较合适,因为react的机制是每次变动都会重新执行usePagination这个hook。

但我在这个issue开头表达过了,这种情况用的比较少,使用methodHandler的推断类型对开发者的收益是比较大的,所以我其实是倾向于这个方案的,但现在的问题是如何兼容上面这种情况。

JOU-amjs avatar Aug 11 '23 09:08 JOU-amjs

将 send 时传的额外参数变成 any 就好了,比如在 send 的参数类型后加个 & Record<string, any> 之类的来兼容额外的参数

Nakus0426 avatar Dec 08 '23 10:12 Nakus0426

@JOU-amjs 可以将send的入参类型和onSuccess的sendArgs类型定义成这样type Arg = [ ...Parameters<typeof request>,...any ] image

songpeng154 avatar Mar 22 '24 01:03 songpeng154

https://github.com/alovajs/alova/pull/375 我提了一个pr可以看一下能否解决问题 f129c351eb12bbb1a50cbaf091a4479 9c034b0258bd38681eda11ae2b79955

czhlin avatar Jun 08 '24 14:06 czhlin

已按各位预期的设计发布,升级到[email protected]可使用

JOU-amjs avatar Jun 11 '24 03:06 JOU-amjs