【发布时间】:2021-09-20 22:21:30
【问题描述】:
对不起,令人困惑的标题!我会尽量在这里尽可能清楚。给定以下接口(由openapi-typescript 作为 API 定义生成):
TypeScript playground 看看这个在行动中
export interface paths {
'/v1/some-path/:id': {
get: {
parameters: {
query: {
id: number;
};
header: {};
};
responses: {
/** OK */
200: {
schema: {
id: number;
name: string;
};
};
};
};
post: {
parameters: {
body: {
name: string;
};
header: {};
};
responses: {
/** OK */
200: {
schema: {
id: number;
name: string;
};
};
};
};
};
}
上述接口paths 将有许多由字符串标识的路径,每个路径都有一些可用的方法,然后定义参数和响应类型。
我正在尝试编写一个通用的apiCall 函数,这样给定一个路径和一个方法就知道所需参数的类型和返回类型。
这是我目前所拥有的:
type Path = keyof paths;
type PathMethods<P extends Path> = keyof paths[P];
type RequestParams<P extends Path, M extends PathMethods<P>> =
paths[P][M]['parameters'];
type ResponseType<P extends Path, M extends PathMethods<P>> =
paths[P][M]['responses'][200]['schema'];
export const apiCall = (
path: Path,
method: PathMethods<typeof path>,
params: RequestParams<typeof path, typeof method>
): Promise<ResponseType<typeof path, typeof method>> => {
const url = path;
console.log('params', params);
// method & url are
return fetch(url, { method }) as any;
};
但是这不能正常工作,我收到以下错误:
-
paths[P][M]['parameters']['path']->Type '"parameters"' cannot be used to index type 'paths[P][M]'即使它确实有效(如果我这样做type test = RequestParams<'/v1/some-path/:id', 'get'>然后test显示正确的类型)
知道如何实现吗?
【问题讨论】:
-
你能确定这里的代码是minimal reproducible example吗?我有a few issues;一个是
'path'确实似乎在这里应该是一个错误,我无法重现您的“method由于某种原因变成never类型”。大概你希望apiCall成为一个通用函数,但我看不出你的问题是什么。此外,您可能希望将其拆分为多个问题;您的错误 1 和 2 似乎彼此相关,但 3 只是您在代码中遇到的不同问题。 -
我可以减少一点,但它可能会消除主要问题 -> 主要是路径和方法是确定响应类型所必需的,而从某种意义上说,它们都是“通用的”它们是由路径决定的。问题 1 和问题 2 相同,问题 3 可能不是问题 -> 参见我添加的 TypeScript 游乐场
标签: ajax typescript openapi type-inference typescript-generics