typescript联合类型如何方便地访问属性?

新手上路,请多包涵

image.png

如图,声明的filter是个联合类型,一部分有days属性一部分没有(下面的判断同理)

一个个判断是否含有该属性实在是太不优雅了

然而注释掉的这种写法也会报ts错误,同样的不能这样写

是否有更优雅的写法呢?

这里有个demo能帮忙阐述我的问题

interface A{
  a: string
}

interface B{
  b: number
}
interface C{
  c: string
}
type ABC = A | B | C

const fn = (param: ABC) => {
  const obj = param.b // 这里无法通过ts检查,因为属性b并不是一定存在的
  // 在官方实例中,这种情况应该使用类型保护,也就是下方的写法
  // 但实际业务中通常需要访问很多属性,要一个个in判断实在是太冗余了
  // 有更优雅的写法吗?
  // if ('b' in param) {
  //   obj = param.b
  // }
  return obj
}

阅读 6.5k
1 个回答

param 所拥有的属性并不能非常明确的确定,TypeScript 就不能安全的判断哪些属性可用,哪些不可用,所以不会通过检查。

如果要让 TypeScript 明白,属性确实可用,那就必须证明 param 确实是某种类型,这不是抽象层面的,而是实现层面的。通常在 JS 中我们会这么检查:

if (param.b) {
    // 这说明 param 中有 b 这个属性,符合 B 类型的特征
}

在 TypeScript 中可以定义一个 isB() 函数来进行判断,

function isB(it: ABC): it is B {
    return (it as B).b !== undefined;
}

注意它的返回类型,不是单纯的 boolean,而是一个类型判定,有了这个判定函数之后,就可以在业务代码中这样写:

const fn = (param: ABC) => {
    if (isB(param)) {
        const obj = param.b;    // 这里就可以识别 param 是 B 类型了
    }
}

image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进