openapi-generator生成的TypeScript-Angular接口只读字段为何不可为空?
解决TypeScript OpenAPI生成器中只读字段导致的请求类型不匹配问题
问题场景
用OpenAPI 3 TypeScript代码生成器给Angular项目生成登录接口时,得到的类型定义如下:
export interface TokenObtainPair { email: string; password: string; readonly access: string; }
编写登录函数时,只传入email和password,TypeScript直接报错:
error TS2739: Type '{ email: string; password: string; }' is missing the following properties from type 'TokenObtainPair': access
手动给对象加access: ''能暂时解决,但这完全没必要——只读字段本来就应该是接口响应返回的内容,请求时根本不需要传。
解决方案
1. 拆分OpenAPI规范中的请求/响应模型(最优解)
问题根源是OpenAPI schema把请求和响应的字段混在了一起。直接拆分出两个独立的schema:一个用于登录请求,一个用于响应。示例如下:
components: schemas: TokenObtainPairRequest: type: object required: [email, password] properties: email: type: string password: type: string TokenObtainPairResponse: type: object required: [access] properties: access: type: string
重新生成代码后,TypeScript会自动生成两个独立的接口,请求用TokenObtainPairRequest,响应接收用TokenObtainPairResponse,彻底避免类型不匹配的问题。
2. 用TypeScript工具类型提取请求字段
如果暂时没法修改OpenAPI规范,直接在代码里用Pick工具类型从生成的接口中提取需要的字段:
// 只保留email和password作为请求类型 type TokenObtainPairRequest = Pick<TokenObtainPair, 'email' | 'password'>; login(Email: string, Password: string): Observable<TokenObtainPair> { const pair: TokenObtainPairRequest = { email: Email, password: Password, }; return this.apiService.apiTokenCreate({ TokenObtainPair: pair }); }
这种方式不用修改生成的代码,也能满足请求时的类型校验要求。
3. 配置代码生成器忽略只读字段的必填性
检查你使用的OpenAPI代码生成器(比如openapi-generator-cli)的配置,是否有参数可以控制只读字段的处理。例如,用openapi-generator-cli时,可以在配置文件里添加:
# openapi-generator-config.yaml typescript-angular: modelPropertyNaming: camelCase optionalReadOnly: true # 将所有只读字段设为可选
重新生成代码后,access字段会变成readonly access?: string;,此时请求对象里不传access也不会触发类型错误。
内容的提问来源于stack exchange,提问作者Tillmann
相关产品推荐
相关产品推荐

