如何验证打字稿中“未知”类型参数的属性?

时间:2020-06-28 08:06:36

标签: typescript

我敢肯定,这里有些超级基础的东西,但是我不太清楚。这是我第一次探究unknown类型,并且正在使用它来验证用户配置文件。

我知道您必须基本上检查该未知类型的值才能获取打字稿,以获取有关对象本身的越来越多的信息。这就是我到目前为止所拥有的

function validateJsonOverride(override: unknown) {
  if (typeof override !== "object") {
    throw new Error("Property `overrides` must be an array of objects");
  }
  if (override == null) {
    throw new Error("Elements in `overrides` cannot be null or undefined");
  }
  
  if (!("a" in override)) {
    throw new Error("Property `a` is required for json overrides");
  }
  if (!("b" in override)) {
    throw new Error("Property `b` is required for json overrides");
  }
  const {a, b} = override;
  return {
    a,
    b,
  };

但是现在在const {a, b} = override;行,我得到了一个错误Property 'a' does not exist on type '{}'.ts(2339)

您应该如何澄清打字稿的类型,以使ab存在。

我还将其复制到Typescript playground中,以便于重播

2 个答案:

答案 0 :(得分:0)

对于您来说,User-Defined type guards可以起作用:

interface Something {
    a: string
    b: string
}

function overrideIsSomething(override: any): override is Something {
    return typeof override.a === 'string' && typeof override.b === 'string'
}

您可以像这样使用overrideIsSomething

if (overrideIsSomething(override)) {
    // override is Something in this context
    const {a, b} = override;
    return {
        a,
        b,
    };
  }

已编辑

在这种特定情况下,利用可选的链接实现运行时安全:

function overrideIsSomething(override: any): override is Something {
    return typeof override?.a === 'string' && typeof override?.b === 'string'
}

它更简单,更有效,但是如果您想要最安全的方式,请查看zerkms的答案。

答案 1 :(得分:0)

绝对安全的方式是

interface Something {
    a: string
    b: string
}
function overrideIsSomething(override: unknown): override is Something {
    function isSomethingLike(given: unknown): given is Partial<Record<keyof Something, unknown>> {
        return typeof given === 'object' && given !== null;
    }
    
    return isSomethingLike(override) && typeof override.a === 'string' && typeof override.b === 'string'
}

因此,您首先断言它具有必要的形状,然后检查其属性类型。