【发布时间】:2021-03-03 02:48:38
【问题描述】:
我通过实现一个强类型的休息请求机制来玩打字稿。
让代码说话:
使用这种类型,我想定义路由和相关对象类型之间的映射:
export interface RoutesMapping {
api1: {
users: UserApiModel
products: ProductApiModel,
}
api2: {
"other-route": OtherModel1,
"another-one-route": OtherModel2
}
}
export type ApiScope = keyof RoutesMapping
以下函数是我愿意用来发出 POST 请求的函数
export type RestApiPostResponse<T = any> = {
result: boolean
data: T
}
export function restPost<S extends keyof RoutesMapping = "api1", T extends keyof RoutesMapping[S] = keyof RoutesMapping[S]>(
route: T,
// nervermind this object, is out of scope for the question
options: ApiRequestOptions<S, any> = {}
): Promise<RestApiPostResponse<RoutesMapping[S][T]>> {
const url = apiUtils.buildUrl(route as string, options)
const { payload, headers, isProtected } = options
return post({
url,
isProtected,
payload,
headers
});
}
我希望通过以下方式调用这个函数
const data = await restPost("users")
make typescript 通过作用域和路由推断返回类型。
实际上,使用默认类型参数,它可以工作:
问题是当我想以这种方式调用另一个api时:
const data = await restPost<"api2">("other-route")
不幸的是,它不起作用,它推断出所有可能的类型
解决问题的唯一方法是显式添加第二个类型参数
如何在第二个场景中不用添加第二个类型参数的情况下使用所有这些?
【问题讨论】:
-
请考虑修改此处的代码,以便构成一个适合放入独立 IDE 的 minimal reproducible example,例如 The TypeScript Playground,这表明您的问题并且没有其他问题(例如,未声明的类型或值)存在。相关,images of code or errors are not as helpful as you might think;对我来说,如果我不能将它复制并粘贴到我的 IDE 中,我就不能轻松地用它来诊断或提出问题的解决方案。祝你好运!
-
我最后添加了指向操场@jcalz的链接
-
您的游乐场链接无效
-
@ritaj 我用稍微改变的版本更新了链接:操场不是用来运行的,问题是 100% 的类型检查,在最后的代码行中有一条注释解释了什么我正在努力实现
-
@Apperside 谢谢...查看this question 及其答案,看看它是否解决了您的问题。 TS 中没有部分类型参数推断;我知道的解决方法是柯里化和虚拟参数,请参阅here。
标签: typescript typescript-typings typescript-generics