如何通过@rtk-query/codegen-openapi访问生成的LangDto类型?
解决@rtk-query/codegen-openapi生成类型无法被tst-reflect反射的问题
核心原因
@rtk-query/codegen-openapi仅生成TypeScript静态类型,这些类型在编译后会被完全擦除,本身不附带任何运行时元数据。tst-reflect需要通过编译时注入额外代码才能获取类型信息,而默认生成的DTO类型并不满足它的触发条件,导致getProperties返回空值。
可行解决方案
1. 自定义codegen模板生成运行时元数据
@rtk-query/codegen-openapi支持自定义Handlebars模板,可在生成类型的同时输出包含属性信息的运行时对象,无需依赖第三方反射工具。
- 编写自定义模板文件(比如
custom-dto-template.hbs):export interface {{interfaceName}} { {{#each properties}} {{name}}: {{type}}; {{/each}} } export const {{interfaceName}}Metadata = { properties: [ {{#each properties}} { name: '{{name}}', type: '{{type}}' }, {{/each}} ] }; - 在codegen配置中指定该模板:
{ "schemaFile": "./swagger.json", "template": "./custom-dto-template.hbs", "outputFile": "./generated-api-types.ts" } - 在React组件中直接使用生成的元数据:
import { LangDtoMetadata } from './generated-api-types'; // 遍历属性列表 LangDtoMetadata.properties.forEach(prop => { console.log(`属性名:${prop.name},类型:${prop.type}`); });
2. 生成Zod/IO-TS运行时类型Schema
如果需要同时获得类型校验能力,可通过自定义模板生成Zod或IO-TS的schema,这类库本身携带完整的运行时类型信息。
示例Zod模板片段:
import { z } from 'zod'; export const {{interfaceName}}Schema = z.object({ {{#each properties}} {{name}}: {{zodType type}}, {{/each}} }); export type {{interfaceName}} = z.infer<typeof {{interfaceName}}Schema>;
(需自行实现zodType辅助函数,将Swagger类型映射为Zod方法,比如number对应z.number())
在组件中访问属性:
import { LangDtoSchema } from './generated-api-types'; // 获取所有属性名 const propertyNames = Object.keys(LangDtoSchema.shape); // 获取属性的可选性等详细信息 const propertyDetails = Object.entries(LangDtoSchema.shape).map(([name, schema]) => ({ name, isOptional: schema.isOptional() }));
3. 修复tst-reflect配置(不推荐)
如果坚持使用tst-reflect,需确保项目配置正确:
- 安装
tst-reflect-transformer并在tsconfig.json中配置:{ "compilerOptions": { "plugins": [{ "transform": "tst-reflect-transformer" }], "experimentalDecorators": true, "emitDecoratorMetadata": true } } - 修改codegen模板,给生成的接口添加
tst-reflect的@reflect()装饰器:
这种方式依赖编译插件,且需要修改生成逻辑,稳定性和可维护性不如前两种方案。import { reflect } from 'tst-reflect'; @reflect() export interface {{interfaceName}} { {{#each properties}} {{name}}: {{type}}; {{/each}} }
内容的提问来源于stack exchange,提问作者techie18
相关产品推荐
相关产品推荐

