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

TypeScript中使用in操作符时如何避免代码重复?

解决TypeScript联合类型中重复检查属性的问题

你遇到的问题本质是TypeScript的类型缩小机制需要明确的属性存在性检查——虽然逻辑上真值判断隐含了属性存在,但TS的类型系统不会自动推导这一点。下面给你两种可行的解决方案:

方案一:针对特定类型写自定义类型守卫

既然你明确要判断obj是否为A类型,直接写一个专门的类型守卫函数最直观,完全避免重复写属性名:

type A = {
    foo: string
    bar: string
}

type B = {
    baz: string
}

type U = A | B;

// 专门判断是否为A类型的守卫
function isA(obj: U): obj is A {
  return 'foo' in obj && !!obj.foo;
}

function f(obj: U) {
    if (isA(obj)) {
        console.log(obj.foo, obj.bar); // TS能正确推断obj是A类型
    }
}

这种方式的好处是类型推断最精准,代码可读性也高,适合固定的联合类型场景。

方案二:通用的真值属性检查工具函数

如果需要一个通用的工具函数处理各种类型,可以通过泛型约束修复你之前的类型谓词错误,同时让TS能推断更精确的类型:

function hasTruthyProp<T, K extends PropertyKey>(obj: T, prop: K): obj is T & Record<K, NonNullable<T[K]>> {
  return prop in obj && !!obj[prop as keyof T];
}

// 回到你的例子中使用:
function f(obj: U) {
    if (hasTruthyProp(obj, 'foo')) {
        console.log(obj.foo, obj.bar); // TS会自动排除B类型,推断obj为A
    }
}

这个函数通过泛型K约束属性名的类型,返回类型中把该属性标记为非空值。因为B类型没有foo属性,TS会自动在if块里把obj缩小为A类型,自然能访问bar。

需要注意的是,通用函数在复杂联合类型下可能需要更精细的类型处理,但针对你的场景完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:15:12