TypeScript中如何判断父接口类型对象所属的扩展子接口
方案1:使用in运算符做自动类型收窄
TypeScript原生支持通过in运算符判断属性是否存在来缩小类型范围,直接替换你原来的判断写法即可:
function handleItem(obj: ParentItem) { if ('fooone' in obj) { // 此处TS会自动将obj识别为ChildItemOne类型 console.log(obj.fooone); } else if ('footwo' in obj) { // 此处TS会自动将obj识别为ChildItemTwo类型 console.log(obj.footwo); } }
该方案适合判断逻辑少、不需要复用的场景。
方案2:自定义类型守卫函数
如果需要在多处做类型判断,可以封装可复用的类型守卫,用类型谓词明确标记返回值对应的类型:
function isChildItemOne(obj: ParentItem): obj is ChildItemOne { return 'fooone' in obj; } function isChildItemTwo(obj: ParentItem): obj is ChildItemTwo { return 'footwo' in obj; } // 使用示例 function handleItem(obj: ParentItem) { if (isChildItemOne(obj)) { console.log(obj.fooone); } else if (isChildItemTwo(obj)) { console.log(obj.footwo); } }
方案3:改造为可辨识联合(工程化推荐)
如果后续还会扩展更多子接口,建议给所有接口增加唯一的辨识字段,避免后续属性名重复导致判断逻辑出错:
interface ParentItem { foo: number; type: 'child1' | 'child2'; // 增加可辨识字段 } interface ChildItemOne extends ParentItem { type: 'child1'; // 子接口固定辨识字段值 fooone: string; } interface ChildItemTwo extends ParentItem { type: 'child2'; // 子接口固定辨识字段值 footwo : string; } // 使用时直接判断辨识字段即可,TS会自动收窄类型 function handleItem(obj: ParentItem) { if (obj.type === 'child1') { console.log(obj.fooone); } else if (obj.type === 'child2') { console.log(obj.footwo); } }
这种方法判断逻辑更直观,后续维护成本更低,是TS中处理多子类型判断的常用最佳实践。
内容的提问来源于stack exchange,提问作者Sid Anand
相关产品推荐
相关产品推荐

