如何判断混合值类型是否属于某一自定义混合类型集合?
解决方案
你遇到的问题核心是:TypeCollection1这类联合类型别名只存在于TypeScript编译阶段,运行时没有对应的构造函数,所以instanceof根本无法生效。下面是几种更优雅的解决思路:
1. 自定义类型守卫函数
把类型判断逻辑封装成专门的守卫函数,既复用代码,又能让TypeScript自动完成类型窄化:
// 先补充具体类型定义示例 type Type1 = { example_key: string; foo: number }; type Type2 = { example_key: string; bar: boolean }; type Type3 = { example_key: string; baz: string }; type TypeCollection1 = Type1 | Type2 | Type3; type Type4 = { other_key: number }; type Type5 = { other_key: number }; type Type6 = { other_key: number }; type TypeCollection2 = Type4 | Type5 | Type6; // 自定义类型守卫,明确判断逻辑 function isTypeCollection1(obj: any): obj is TypeCollection1 { return "example_key" in obj; } function doSomething(myObject: TypeCollection1 | TypeCollection2): void { if (isTypeCollection1(myObject)) { // 这里myObject会被自动推断为TypeCollection1类型 console.log(myObject.example_key); } else { // 自动推断为TypeCollection2类型 console.log(myObject.other_key); } }
2. 给类型添加区分标签(推荐)
如果能修改Type1-Type6的定义,给每个集合的类型加一个唯一标识标签,这是TypeScript处理联合类型最直观的方式:
// 给TypeCollection1的类型统一加标签 type Type1 = { type: 'collection1'; foo: number }; type Type2 = { type: 'collection1'; bar: boolean }; type Type3 = { type: 'collection1'; baz: string }; type TypeCollection1 = Type1 | Type2 | Type3; // 给TypeCollection2的类型统一加标签 type Type4 = { type: 'collection2'; x: number }; type Type5 = { type: 'collection2'; y: string }; type Type6 = { type: 'collection2'; z: boolean }; type TypeCollection2 = Type4 | Type5 | Type6; function doSomething(myObject: TypeCollection1 | TypeCollection2): void { if (myObject.type === 'collection1') { // 自动推断为TypeCollection1 console.log(myObject.foo || myObject.bar || myObject.baz); } else { // 自动推断为TypeCollection2 console.log(myObject.x || myObject.y || myObject.z); } }
标签可以叫type/kind等任意名字,只要每个集合的标签值唯一即可,完全不需要额外判断逻辑。
3. 优化现有键检查逻辑
如果不想修改原有类型,其实TypeScript在看到"example_key" in myObject时,已经能自动把myObject的类型窄化为TypeCollection1,不需要额外断言:
function doSomething(myObject: TypeCollection1 | TypeCollection2): void { if ("example_key" in myObject) { // 直接访问TypeCollection1的属性即可,TypeScript已自动推断类型 console.log(myObject.example_key); } else { console.log(myObject.other_key); } }
内容的提问来源于stack exchange,提问作者Conrad Neumann
相关产品推荐
相关产品推荐

