访问对象时泛型导致的类型收窄丢失问题
访问对象时泛型导致的类型收窄丢失问题
看起来你遇到了泛型使用时类型收窄丢失的问题,先把你给出的代码和场景整理清楚,咱们一步步来捋:
我有一个包含子对象的结构,子对象里按key存储了不同的函数:
const listOps = { lists: { create: { schema: SchemaLists.listsCreate, db: DbUsersService.listsCreate, }, }, } as const; type ListModelKind = keyof typeof listOps; export class ApiLists { static async handleOp< T extends ListModelKind, K extends keyof (typeof listOps)[T], >({ listModel, op, params }: { listModel: T; op: K; params: unknown; }) { // 核心问题:访问 listOps[listModel][op] 时,TS无法正确收窄类型 const operation = listOps[listModel][op]; // 想调用 operation.db 或 operation.schema 时,类型推导失效 } }
我猜你是在handleOp方法里,当通过泛型参数listModel和op访问listOps的属性时,TypeScript没办法自动收窄到具体的操作类型,导致你没法安全地访问schema或者db属性,甚至没办法让params的类型和对应schema的输入类型绑定,对吧?
给你两个实用的解决思路:
1. 直接通过类型断言明确类型(简单直接)
如果只是想快速解决类型收窄问题,可以在访问listOps属性时添加类型断言,让TS明确知道当前操作的具体类型:
export class ApiLists { static async handleOp< T extends ListModelKind, K extends keyof (typeof listOps)[T], >({ listModel, op, params }: { listModel: T; op: K; params: unknown; }) { // 用类型断言关联泛型参数,让TS推导正确类型 const operation = listOps[listModel][op] as (typeof listOps)[T][K]; // 现在可以安全访问schema和db,类型推导完全正常 const validatedParams = operation.schema.parse(params); const result = await operation.db(validatedParams); return result; } }
2. 优化泛型关联,让类型自动推导(更优雅)
如果想让params的类型也自动和对应操作的schema输入类型绑定,我们可以进一步优化泛型定义,让TS全程自动跟踪类型:
// 先提取所有操作的通用类型 type ListOperation = typeof listOps[keyof typeof listOps][keyof typeof listOps[keyof typeof listOps]]; // 定义一个工具类型,用来提取对应操作的schema输入参数类型 type OperationParams<Op extends ListOperation> = Parameters<Op['schema']['parse']>[0]; export class ApiLists { static async handleOp< T extends ListModelKind, K extends keyof (typeof listOps)[T], Op extends (typeof listOps)[T][K] >({ listModel, op, params }: { listModel: T; op: K; params: OperationParams<Op>; }) { const operation = listOps[listModel][op] as Op; const validated = operation.schema.parse(params); return await operation.db(validated); } }
这样调整后,不仅operation的类型会被正确收窄,连params参数都会自动匹配对应操作的schema输入类型,调用的时候TS会自动做类型校验,完全避免了类型丢失的问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

