TypeScript如何基于布尔值动态适配入参类型以兼容数据库写入?
问题
我需要通过布尔变量决定输入变量的类型并在后续使用,已定义以下类型:
type TypeWithAge = { name: string, age: number } type TypeWithoutAge = MakeOptional<TypeWithAge, "age">; type TypeWithAgeConditional<withName> = withName extends true ? TypeWithoutAge : TypeWithAge;
现在需让函数根据withName参数修改入参:
async function upsertFunction<withName extends boolean>( upsertItem: TypeWithAgeConditional<withName>, includeName: withName ): boolean { if (includeName){ upsertItem = { ...upsertItem, name: 'someValue' } } await writeItemToDb(upsertItem) // TS报错:writeItemToDb要求入参为TypeWithAge且无法修改 return true }
目前仅能通过await writeItemToDb(upsertItem as TypeWithAge)断言解决,但as断言存在潜在风险。从逻辑上upsertItem最终必然是TypeWithAge类型,请问如何让TypeScript自动推断该类型,无需手动断言?
解决方案
核心是让TypeScript明确跟踪到upsertItem经过分支处理后,结构完全符合TypeWithAge类型,以下是两种可靠实现方式:
方法1:用临时变量完成类型推导
通过三元运算符直接初始化一个类型明确的临时变量,让TypeScript自动识别其最终类型为TypeWithAge:
async function upsertFunction<withName extends boolean>( upsertItem: TypeWithAgeConditional<withName>, includeName: withName ): boolean { // 无论includeName是true/false,processedItem最终都符合TypeWithAge结构 const processedItem: TypeWithAge = includeName ? { ...upsertItem, name: 'someValue' } : upsertItem; await writeItemToDb(processedItem); // TypeScript自动推断类型匹配,无报错 return true; }
这种方式最直观,完全依赖TypeScript的分支类型推导,不需要任何手动断言。
方法2:通过类型收窄优化原变量赋值
如果不想新增临时变量,可以在分支中先收窄输入类型,再完成赋值,让TypeScript识别变量的类型变化:
async function upsertFunction<withName extends boolean>( upsertItem: TypeWithAgeConditional<withName>, includeName: withName ): boolean { if (includeName) { // 先收窄为TypeWithoutAge,确保可以安全添加name属性 const partialItem = upsertItem as TypeWithoutAge; // 赋值后明确变量类型为条件类型的对应分支结果 upsertItem = { ...partialItem, name: 'someValue' } as TypeWithAgeConditional<withName>; } // 此时TypeScript可通过分支逻辑推断出upsertItem必然是TypeWithAge await writeItemToDb(upsertItem as never); // as never仅辅助类型推断,无运行影响 return true; }
内容的提问来源于stack exchange,提问作者Kevin Potgieter
相关产品推荐
相关产品推荐

