1. 定义函数
function unionToIntersection<T, U>(arg: T | U): T & U {
if ('type' in arg && arg.type === 'T') {
return arg as T & U;
}
return arg as T & U;
}
function intersectionToUnion<T, U>(arg: T & U): T | U {
return arg as T | U;
}
2. 实际应用意义
- 接收联合类型参数并返回交叉类型结果:
- 在实际应用中,当你需要处理可能是多种类型之一的数据,但希望以一种更具约束性(结合多种类型特性)的方式返回结果时很有用。例如,在一个图形绘制库中,可能有圆形和矩形两种图形类型,某个操作可能接收圆形或矩形(联合类型),但返回的结果是既包含圆形又包含矩形公共特性的交叉类型,以用于后续通用的渲染逻辑。
- 接收交叉类型参数并返回联合类型结果:
- 当你有一个具有多种特性(交叉类型)的数据,需要根据不同的逻辑将其作为不同的单一类型(联合类型)来处理时会用到。比如在一个游戏角色系统中,角色可能同时具有“玩家控制”和“可攻击”等特性(交叉类型),但在某些场景下,可能需要将其作为单纯的“玩家控制”对象或“可攻击”对象(联合类型)来处理不同的交互逻辑。
3. 类型检查问题及解决办法
- 接收联合类型参数并返回交叉类型结果:
- 问题:在函数内部,由于参数是联合类型,TypeScript 不确定具体类型,可能导致类型检查错误,例如访问某个类型特有的属性时会报错。
- 解决办法:可以使用类型守卫(如上述代码中的
'type' in arg
这种自定义类型守卫)来缩小类型范围,确保在访问属性时类型是正确的。
- 接收交叉类型参数并返回联合类型结果:
- 问题:从交叉类型转换为联合类型时,可能丢失部分类型信息,导致在后续使用联合类型返回值时,TypeScript 无法准确推断出具体类型,引发类型错误。
- 解决办法:在调用该函数后,使用类型断言或类型守卫进一步明确类型,以便在后续代码中正确处理返回值的不同类型情况。例如:
let result = intersectionToUnion({a: 1, b: 'test'} as {a: number} & {b: string});
if ('a' in result) {
// result 被缩小为 {a: number} 类型
console.log(result.a);
}