如何解决导入 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
)似乎都不起作用,导致少数其他错误之一(可以' t 查找或导入模块、错误的扩展名等)。我希望得到一个关于 Typescript 如何找到这个对象的简明解释,或者解释我在构造这个对象时出错的地方。目前,我的文件结构是:
src/
|- main.ts
|- App.vue
|- ...
|- rigging/
| |- api.ts
|
|- types/
|- proto.d.ts
在根(src
上方)我也有 vue.config.js
和 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>,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
,但这违反了定义文件约定。
我强烈建议使用 openapi-generator
有用的前端生成器:
typescript-axios
typescript-fetch
我在 2 个大型项目中将 typescript-fetch
与 React
结合使用,效果非常好。
生成示例:
// cli or package.json script
npx @openapitools/openapi-generator-cli generate -i ./api.json -g typescript-axios -o ./generated/api/ --additional-properties=typescriptThreePlus=true
CLI 最新版本的可执行版本
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。