标题可能不太正确,大致效果如下
// 每个 url 都对应着一个 params,怎么写比较优雅,有较好的提示性
function get(url: '/login', params: {username:string, password: string})
function get(url: '/logout')
function get(url: '/changePassword', params: {username: string, oldPwd: string, newPwd:string})
function get(url:string, params?:any){
// ....
console.log(`${url}::${JSON.stringify(params)}`)
}
ts中有没有存在一种类型,或者说特殊的写法,可以将 url
和params
类型进行映射?
比如说
// 模拟代码
typeObj = {'/login': {username:string, password: string}}
//在function的声明中利用 keyOf in 之类的方式依次取出,就能实现重载的效果?
提供思路也可以,当然最好是直接给个demo, 十分感谢!
简单版本
如果只是为了声明方便的话,只要使用以下语句即可,而且使用
get
函数的时候,能根据传入的url
值,去推断params
的值Playground
更近一步
对于使用
get
的时候,TS 已经足够聪明了,不过对于在get
内部去使用时,TS 还不够聪明.比如下面的情况,就会报错,提示ChangePasswordParam
类型中不存在password
,这就很反直觉.如果要使用password
,需要通过类型断言,将params
指定为一个更具体的类型LoginParam
,才能使用password
.Playground
不过这样看着就很别扭,根据上下文,明明在
url === '/login'
就已经可以判定params
的类型,却还得手动在加一层断言,而且这样手动加的情况,是最容易出问题的,比如下面这样,明显是错的,但是 TS 就是不报错.这仅仅只有一行还好,我们一眼就能看出来了,但是如果代码一多,我估计就不是很容易发现了.其实还是有办法能解决的,只是需要稍微变通一下,我们看看下面的例子
这种情况下,TS 是正确推断出来 obj 的类型的.而如果把 ObjType 换成数组(元组)的联合类型,也依然能生效,如下
那我们的参数列表,其实就是一个数组结构,只要改变一下写法,使用 ES6 的 Rest 参数,就能获得跟上面一样的效果
最终的版本
Playground