如何实现TypeScript中ERPTypes的model与fields类型动态关联?
动态关联ERP模型与字段类型的TypeScript实现
问题描述
我定义了包含多对象类型的ERPTypes:
type ERPTypes = { 'res.company': { account_enabled_tax_country_ids?: unknown account_fiscal_country_id?: false | [number, string] account_folder?: false | [number, string] } }
需要创建readQuery函数,要求参数payload的model字段只能是ERPTypes的键,同时fields字段的类型要根据传入的model动态匹配ERPTypes中对应对象的键类型,而非硬编码固定类型。当前代码中fields的类型是硬写的,无法适配多个模型:
export type ReadPayloadT = { model: keyof ERPTypes ids: number[] fields?: (keyof ERPTypes['res.company'])[] // <---- 需动态关联model对应的类型 with_context?: string with_company?: number } export const readQuery = ( payload: ReadPayloadT ): Promise<ERPTypes[keyof ERPTypes][]> => { return axios .post(process.env['E_URL'] + '/api/v2/read', payload, { headers: { DATABASE: process.env['E_DB']!, Authorization: 'Bearer ' + token, }, }) .then((res) => res.data) } readQuery({ model: 'res.company', ids: [3], fields: ['account_fiscal_country_id'], })
解决方案
通过泛型类型实现model与fields的动态关联,具体修改如下:
修改后的完整代码
type ERPTypes = { 'res.company': { account_enabled_tax_country_ids?: unknown account_fiscal_country_id?: false | [number, string] account_folder?: false | [number, string] } // 可扩展更多ERP模型 'res.partner': { name?: string email?: string phone?: string } } // 泛型Payload类型,绑定model与对应字段 export type ReadPayloadT<M extends keyof ERPTypes> = { model: M ids: number[] fields?: (keyof ERPTypes[M])[] with_context?: string with_company?: number } // 泛型函数,返回对应模型的数组类型 export const readQuery = <M extends keyof ERPTypes>( payload: ReadPayloadT<M> ): Promise<ERPTypes[M][]> => { return axios .post(process.env['E_URL'] + '/api/v2/read', payload, { headers: { DATABASE: process.env['E_DB']!, Authorization: 'Bearer ' + token, }, }) .then((res) => res.data) } // 使用示例:自动匹配对应模型的字段 readQuery({ model: 'res.company', ids: [3], fields: ['account_fiscal_country_id'] // 仅提示res.company的键 }) readQuery({ model: 'res.partner', ids: [5], fields: ['name', 'email'] // 仅提示res.partner的键 })
关键说明
- 泛型
M被约束为keyof ERPTypes,确保model只能传入ERPTypes中存在的模型键 fields的类型(keyof ERPTypes[M])[]会根据M的具体值动态推导,实现model与fields的强类型关联- 返回类型
Promise<ERPTypes[M][]>让函数返回的数组元素类型与传入的模型严格对应,避免了联合类型带来的类型模糊
内容的提问来源于stack exchange,提问作者Ilijanovic
相关产品推荐
相关产品推荐

