代码之家  ›  专栏  ›  技术社区  ›  MgSam Brad M

检查属性是否存在的类型保护

  •  3
  • MgSam Brad M  · 技术社区  · 7 年前

    我知道 type guards 可用于区分联合类型。但是,是否有可能在传入的未知类型上检测到属性存在?

    此代码不起作用。

    function foo(bar: unknown | { createdDate: Date }) {
        if (bar.createdDate)
            alert(bar.createdDate); //Doesn't work
    }
    

    这也不是:

    function foo(bar: unknown | { createdDate: Date }) {
        if ('createdDate' in bar)
            alert(bar.createdDate); //Doesn't work
    }
    

    bar any 确实有效,但编译器没有缩小 if 陈述它在打字 bar.createdDate 任何 .

    function foo<T extends (unknown | { createdDate: Date })>(bar: T) {
        if ('createdDate' in bar)
            alert(bar.createdDate); //Doesn't work
    }
    

    有没有办法确认未知类型上存在属性,然后让编译器适当地缩小该类型的范围?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Titian Cernicova-Dragomir    7 年前

    unknown “吃掉”任何其他成员,所以 unknown | { createdDate: Date } == unknown (描述了这种行为 in the PR )

    未知的 可以通过以下方式缩小范围:

    function f20(x: unknown) {
        if (typeof x === "string" || typeof x === "number") {
            x;  // string | number
        }
        if (x instanceof Error) {
            x;  // Error
        }
        if (isFunction(x)) {
            x;  // Function
        }
    }
    

    看来实现您想要的结果的唯一方法是使用自定义类型的保护(因为 typeof x === "typename" is not applicable and instanceof`不适用于接口)

    function foo(bar: unknown) {
      const hasCreatedDate = (u: any): u is { createdDate: Date } => "createdDate" in u;
      if (hasCreatedDate(bar)) {
        alert(bar.createdDate);
      }
    }
    

    或者你可以使用 Object 这不会吃掉任何其他工会成员

    function foo(bar: Object | { createdDate: Date }) {
      if ("createdDate" in bar) {
        alert(bar.createdDate); 
      }
    }
    
    foo({aa: ""})
    
    推荐文章