You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript访问Firebase返回数据提示类型为never的问题如何解决?

问题原因

TypeScript 的控制流分析存在局限性,无法追踪高阶函数回调中对外部变量的赋值操作:
你使用的 forEach 是高阶函数,回调内对 playerOneData、playerTwoData 的赋值属于回调副作用,TS 不会主动分析这类副作用的执行逻辑。因此 TS 会认为这两个变量从初始化后就一直保持 null 值,你写的非空判断 if (playerOneData == null || playerTwoData == null) 会被判定为永远为真,代码永远走不到后续的 console.log 分支,该分支下的两个变量类型就被推断为不可能存在的 never 类型。

解决方案

方案1:替换 forEach 为普通 for...of 循环(推荐)

普通迭代逻辑在 TS 的控制流分析范围内,可以正确识别变量的赋值操作:

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();

  // 替换为for...of遍历
  for (const doc of players.docs) {
    if (doc.id == "PLAYER1_ID") {
      playerOneData = doc.data();
    }
    if (doc.id == "PLAYER2_ID") {
      playerTwoData = doc.data();
    }
  }

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

  // 类型已经可以被正确推断为DocumentData
  console.log(playerOneData.test + " " + playerTwoData.test);
}

方案2:添加类型断言(临时适配)

如果你不想修改循环逻辑,可以在访问属性时手动指定类型:

console.log((playerOneData as FirebaseFirestore.DocumentData).test + " " + (playerTwoData as FirebaseFirestore.DocumentData).test);

额外优化:自定义类型提升安全度

FirebaseFirestore.DocumentData 是泛用的无约束对象类型,后续访问属性时仍可能出现类型提示缺失的问题。你可以自定义玩家数据类型,在调用 data() 时指定类型:

interface Player {
  test: string;
  // 其他玩家字段
}

// 赋值时指定类型
playerOneData = doc.data() as Player;

内容的提问来源于stack exchange,提问作者Nawabu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:36:03