三元运算符生成的对象联合类型不匹配重载函数参数要求
问题描述
我有一个接受不同参数对象的重载函数func,通过三元运算符创建对象arg后传入该函数时,生成的arg是一个不被重载函数接受的对象联合类型。在不修改重载函数的前提下,该如何创建符合要求的对象联合类型?
对应的代码示例:
function func(a: { foo: number }): void function func(a: { foo: string, bar: boolean}): void function func(a: unknown) { console.log(a); } // 这两种调用完全正常 func({ foo: 42 }) func({ foo: 'hello', bar: true }) // 这里会出现类型错误 function test(foo: number | string, bar: boolean) { const arg = typeof foo === 'string' ? { foo, bar } : { foo }; func(arg); // 类型“{ foo: string; bar: boolean; } | { foo: number; }”的参数不能赋给类型“{ foo: number; }”的参数 }
解决方案
1. 直接在分支中调用函数
不用先创建arg变量,直接在三元运算符的两个分支里分别调用func,TypeScript能准确识别每个分支的参数类型,避免联合类型匹配问题:
function test(foo: number | string, bar: boolean) { typeof foo === 'string' ? func({ foo, bar }) : func({ foo }); }
2. 手动类型断言指定联合类型
如果必须保留arg变量,就手动把arg断言为函数重载接受的两种类型的联合,让TypeScript匹配到对应的重载:
function test(foo: number | string, bar: boolean) { const arg = (typeof foo === 'string' ? { foo, bar } : { foo }) as { foo: number } | { foo: string, bar: boolean }; func(arg); }
3. 使用const断言缩小类型范围
在每个分支的对象字面量后添加as const,让TypeScript推断出更精确的字面量类型,这样生成的联合类型能被重载函数正确识别:
function test(foo: number | string, bar: boolean) { const arg = typeof foo === 'string' ? { foo, bar } as const : { foo } as const; func(arg); }
4. 定义类型别名统一断言
先定义一个包含重载函数所有合法参数类型的别名,再用这个别名断言arg,代码可读性会更好:
type FuncArg = { foo: number } | { foo: string, bar: boolean }; function test(foo: number | string, bar: boolean) { const arg = (typeof foo === 'string' ? { foo, bar } : { foo }) as FuncArg; func(arg); }
内容的提问来源于stack exchange,提问作者Serhii Holinei
相关产品推荐
相关产品推荐

