【问题标题】:Unexpected type "never" in Typescript打字稿中的意外类型“从不”
【发布时间】:2021-09-30 13:30:54
【问题描述】:

在我的打字稿代码中,我从 Firebase Firestore 检索数据并在 forEach 循环中过滤有用信息。我将代码压缩为以下测试函数,但错误相同(所有 ID 通常都在变量中):

async function test() {
  let playerOneData: FirebaseFirestore.DocumentData | null = null;
  let playerTwoData: FirebaseFirestore.DocumentData | null = null;
  const players = await db
    .collection("Games/ANY_ID/Players")
    .where(admin.firestore.FieldPath.documentId(), "in", ["PLAYER1_ID", "PLAYER2_ID"])
    .get();

  players.forEach((doc) => {
    if (doc.id == "PLAYER1_ID") {
      playerOneData = doc.data();
    }

    if (doc.id == "PLAYER2_ID") {
      playerTwoData = doc.data();
    }
  });

  if (playerOneData == null || playerTwoData == null) {
    return null;
  }

  console.log(playerOneData.test + " " + playerTwoData.test);
}

最后,当访问“test”属性时,我得到错误“属性测试不存在于类型 never”。

我不明白为什么它甚至应该是 never 类型。据我了解,它应该是 DocumentData 或 null(如定义),我之前直接检查 null。

如果有人能提示我解决方案,那就太好了。

谢谢!

【问题讨论】:

    标签: typescript google-cloud-firestore


    【解决方案1】:

    这是 Typescript 控制流分析的限制。将值 null 分配给局部变量后,它们的类型将缩小为 null,然后当您测试它们是否是从函数返回的 null 时,null 从缩小的类型中消除,留下 @987654326 @ 作为缩小类型。

    当然,forEach 循环应该加宽类型从 nullFirebaseFirestore.DocumentData | null,但 Typescript 不这样做,因为它的设计不是为了知道这个是将这个特定的箭头函数传递给forEach 方法的效果。在其他情况下,箭头函数可能不会从外部范围重新分配任何变量,如果编译器很悲观,那么简单地使用任何箭头函数调用 forEach 会导致所有缩小的类型都被扩大,这会很烦人。

    Typescript 的设计理念不是在所有情况下都选择安全而不是便利, 与编译器需要额外的复杂性才能根据具体情况做出决定。官方问题跟踪器上的This issue 更详细地讨论了这种权衡。

    作为您的情况的解决方法,您可以用常规的for 循环替换对forEach 的调用,这样变量就不会在非本地重新分配;在这种情况下,应该会按预期进行扩大。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多