【问题标题】:typescript type predicate on array数组上的打字稿类型谓词
【发布时间】:2022-12-17 09:13:33
【问题描述】:

我正在使用一个函数来检查变量是否是一个对象而不是 null :

function isRecord(input: any): input is Record<string, any> {
  return input !== null && typeof input === 'object';
}

类型谓词是必需的,因此打字稿接受:

if (isRecord(x)) {
  console.log(x["att"]);
}

我写了另一个接受数组的函数,但是打字稿抱怨 “对象可能是‘空’”:

function areRecords(list: any[]): list is Record<string, any>[] {
  return list.every(element => isRecord(element));
}

if (areRecords(x, y)) {
  console.log(x["att"]);
  console.log(y["att"]);
}

如果我省略“是”,也一样

function areRecords2(list: any[]): boolean {
  return list.every(element => isRecord(element));
}

if (areRecords2([x, y])) {
  console.log(x["att"]);
  console.log(y["att"]);
}

或者如果我使用休息参数:

function areRecords3(...list: any[]): boolean {
  return list.every(element => isRecord(element));
}

if (areRecords3(x, y)) {
  console.log(x["att"]);
  console.log(y["att"]);
}

怎么做才对?

【问题讨论】:

    标签: typescript typeguards


    【解决方案1】:

    使用数组函数,签名提供数组是记录持有者而不是 x 和 y 本身。

    例如:

    const list = [x, y];
    if (areRecords(list)) {
        // Now typescript knows that list is Record<string, any>[];
        // However, it does not know what x and y is, because
        // the function signature only refers to the array.
    }
    

    你可以做的是:

    const list = [x, y];
    if (areRecords(list)) {
        list.forEach(item => console.log(item["att"]));
    }
    

    或者:

    const attributes = [x, y].filter(isRecord).map(value => value["att"]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 2019-03-22
      • 2019-02-10
      • 2022-07-29
      • 1970-01-01
      相关资源
      最近更新 更多