You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何为两个不同接口编写TypeGuard类型守卫?

解决TypeScript联合类型守卫的属性访问报错及多类型兼容问题

先修复当前代码的报错

你写的isA函数报错,是因为TypeScript对联合类型A | B有严格检查:只有属性在联合类型的所有成员中都存在时,才能直接访问。B类型没有foo属性,所以直接访问test.foo会触发错误。

可以用以下两种方式修复:

方式1:使用in操作符(推荐,类型安全)

通过in操作符检查属性是否存在,TypeScript会自动缩小类型范围:

interface A {
  foo: string
}

interface B {
  bar: string
}

function isA(test: A | B): test is A {
  return 'foo' in test;
}

方式2:使用类型断言(临时解决,安全性稍弱)

如果确定检查逻辑可靠,可以用类型断言绕过TypeScript的检查:

function isA(test: A | B): test is A {
  return (test as A).foo !== undefined;
}

兼容同时属于两种类型的对象的类型守卫

当然可以编写这类守卫。如果一个对象同时拥有foo和bar(即同时符合A和B的类型),只要它满足A的判定条件,isA就会返回true——因为TypeScript的类型守卫test is A的含义是“test可以赋值给A”,即便它同时也是B,这个判定依然有效。

如果需要精确区分「仅A」「仅B」「同时是A和B」三种情况,可以编写更细分的守卫:

// 辅助类型,标记“不包含某类型的属性”
type Not<T> = { [K in keyof T]?: never };

// 判断是否仅为A(不同时是B)
function isOnlyA(test: A | B): test is A & Not<B> {
  return 'foo' in test && !('bar' in test);
}

// 判断是否仅为B(不同时是A)
function isOnlyB(test: A | B): test is B & Not<A> {
  return 'bar' in test && !('foo' in test);
}

// 判断是否同时是A和B
function isBothAAndB(test: A | B): test is A & B {
  return 'foo' in test && 'bar' in test;
}

内容的提问来源于stack exchange,提问作者Shiuyin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:53:32