typescript - 导入 OpenAPI 规范生成的类型
问题描述
我正在尝试将生成的类型导入openapi-client-axios
Typescript 文件。高级设置是我有一个后端 Web 服务,从中api.json
生成一个文件,为提供的休息服务创建一个 OpenAPI 规范。然后,我尝试使用该文件创建一个客户端对象,我可以使用该对象在前端 Typescript 中调用该服务。第一部分(Web 服务 -> api.json 文件)可以正常工作。我也能够成功运行:
typegen api.json > proto.d.ts
这会生成一个文件,proto.d.ts
其中包含客户端键入定义。我将此文件src/types/proto.d.ts
放在我的项目中,但在尝试将其导入我实际需要它的代码时遇到了麻烦。该文件src/rigging/api.ts
看起来像这样:
import OpenAPIClientAxios from 'openapi-client-axios';
import { RestClient } from '@types'; // Error occurs here
// These also don't work
// import { RestClient } from './types/proto'
// import { RestClient } from 'proto'
// import { RestClient } from './types/proto.d.ts'
// import { RestClient } from 'proto.d.ts'
// import { RestClient } from '@types/proto'
// ... etc.
const api = new OpenAPIClientAxios({ definition: 'http://localhost:8000/openapi.json' });
const MyRestApi = api.getClient<RestClient>();
export default MyRestApi;
该import { RestClient } ...
行发生的错误似乎很明显:
TS2307:找不到模块“@types”或其对应的类型声明。
对我来说不明显的是如何解决这个问题。我尝试将proto.d.ts
文件重命名为index.d.ts
并移动它,但我似乎无法正确加载它。我试图弄清楚 Typescript 如何加载定义文件,但找不到正在加载的这种生成的类型定义文件的示例。
关于 Typescript、axios 和 Vue(我正在使用的框架)还有很多我不了解的地方,但在我看来,这种导入是我现在陷入的孤立问题。该@
表示法似乎是在线文章所建议的,但无论是它还是点表示法(即./types/proto.d.ts
)似乎都不起作用,从而导致少数其他相同的错误之一(无法找到或导入模块,错误的扩展名, ETC。)。我希望简明扼要地解释一下 Typescript 如何找到这个对象,或者解释一下我在构建这个对象时出错的地方。目前,我的文件结构是:
src/
|- main.ts
|- App.vue
|- ...
|- rigging/
| |- api.ts
|
|- types/
|- proto.d.ts
在根(上src
)我也有vue.config.js
and tsconfig.json
,我知道这可能会影响这一点(即也许我typeRoots
错了?它目前设置为[ "./types" ]
)但我还没有弄清楚。
如果它有用,这是生成的proto.d.ts
文件:
import {
OpenAPIClient,
Parameters,
// UnknownParamsObject,
OperationResponse,
AxiosRequestConfig,
} from 'openapi-client-axios';
declare namespace Components {
namespace Schemas {
export interface Codex {
id: number; // uint64
name: string;
}
}
}
declare namespace Paths {
namespace RestApiGetCodex {
// eslint-disable-next-line no-shadow
namespace Parameters {
export type Id = number; // uint64
}
export interface PathParameters {
id: Parameters.Id; // uint64
}
namespace Responses {
export type $200 = Components.Schemas.Codex;
}
}
}
export interface OperationMethods {
/**
* rest_api_get_codex
*/
'rest_api_get_codex'(
parameters?: Parameters<Paths.RestApiGetCodex.PathParameters>,
data?: any,
config?: AxiosRequestConfig
): OperationResponse<Paths.RestApiGetCodex.Responses.$200>
}
export interface PathsDictionary {
['/codex/{id}']: {
/**
* rest_api_get_codex
*/
'get'(
parameters?: Parameters<Paths.RestApiGetCodex.PathParameters>,
data?: any,
config?: AxiosRequestConfig
): OperationResponse<Paths.RestApiGetCodex.Responses.$200>
}
}
export type RestClient = OpenAPIClient<OperationMethods, PathsDictionary>
解决方案
事实证明,解决方案相对简单:
import OpenAPIClientAxios from 'openapi-client-axios';
import { RestClient } from '@types/proto.d'; // Only drop the 'ts' part of the extension
中的typeRoots
参数tsconfig.json
如下所示:
"typeRoots": [
"./src/types"
],
这使@
能够引用源目录的根目录。但是,导入只删除.ts
文件名的一部分,因此您必须在导入时保留该.d
部分;因此from proto.d
. 另一种方法是从文件系统本身的名称中删除.d
,尽管这违反了定义文件约定。