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

Firebase云函数TypeScript代码复用问题及类型疑问求助

解决Firebase云函数重构后的ESLint警告与类型疑问

一、消除propKey未使用的ESLint警告

1. 确保参数被实际使用

重构后的通用函数必须让propKey参与业务逻辑,比如用来读取Firestore文档的对应字段,从根源上解决未使用警告:

// 通用flag检查函数
async function checkFlag(propKey: 'flagOne' | 'flagTwo', userId: string) {
  const docRef = admin.firestore().collection('users').doc(userId);
  const docSnap = await docRef.get();
  
  // 用propKey动态获取对应flag字段
  return docSnap.exists ? docSnap.data()?.[propKey] === true : false;
}

// 基于通用函数实现两个云函数
export const hasFlagOne = functions.https.onRequest(async (req, res) => {
  await corsManager(req, res, async () => {
    const userId = req.query.userId as string;
    const result = await checkFlag('flagOne', userId);
    handleSnapShot(res, result);
  });
});

export const hasFlagTwo = functions.https.onRequest(async (req, res) => {
  await corsManager(req, res, async () => {
    const userId = req.query.userId as string;
    const result = await checkFlag('flagTwo', userId);
    handleSnapShot(res, result);
  });
});

2. 临时禁用单条语句警告

如果propKey是为未来扩展预留的参数,可通过注释临时关闭ESLint的未使用变量检查:

// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function checkFlag(propKey: 'flagOne' | 'flagTwo', userId: string) {
  // 现有逻辑暂未用到propKey,预留参数位
  // ...
}

二、corsManager与handleSnapShot的参数类型定义

1. corsManager的类型

直接复用Firebase HTTP函数自带的请求、响应类型,结合异步处理器函数定义:

import * as functions from 'firebase-functions';

type CorsManager = (
  req: functions.https.Request,
  res: functions.https.Response,
  handler: () => Promise<void>
) => Promise<void>;

// 示例实现
const corsManager: CorsManager = async (req, res, handler) => {
  res.set('Access-Control-Allow-Origin', '*');
  if (req.method === 'OPTIONS') {
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    return res.status(204).send('');
  }
  await handler();
};

2. handleSnapShot的类型

根据函数功能(处理响应、返回flag检查结果)定义类型:

type HandleSnapshot = (
  res: functions.https.Response,
  flagResult: boolean
) => void;

// 示例实现
const handleSnapShot: HandleSnapshot = (res, flagResult) => {
  res.status(flagResult ? 200 : 404).json({ hasFlag: flagResult });
};

三、完整重构代码示例

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

admin.initializeApp();

// 类型定义
type CorsManager = (
  req: functions.https.Request,
  res: functions.https.Response,
  handler: () => Promise<void>
) => Promise<void>;

type HandleSnapshot = (
  res: functions.https.Response,
  flagResult: boolean
) => void;

// CORS处理逻辑
const corsManager: CorsManager = async (req, res, handler) => {
  res.set('Access-Control-Allow-Origin', '*');
  if (req.method === 'OPTIONS') {
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    return res.status(204).send('');
  }
  await handler();
};

// 响应处理逻辑
const handleSnapShot: HandleSnapshot = (res, flagResult) => {
  res.status(flagResult ? 200 : 404).json({ hasFlag: flagResult });
};

// 通用flag检查逻辑
async function checkFlag(propKey: 'flagOne' | 'flagTwo', userId: string): Promise<boolean> {
  if (!userId) throw new Error('User ID is required');
  const docRef = admin.firestore().collection('users').doc(userId);
  const docSnap = await docRef.get();
  return docSnap.exists ? docSnap.data()?.[propKey] === true : false;
}

// 云函数实例
export const hasFlagOne = functions.https.onRequest(async (req, res) => {
  await corsManager(req, res, async () => {
    try {
      const userId = req.query.userId as string;
      const result = await checkFlag('flagOne', userId);
      handleSnapShot(res, result);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });
});

export const hasFlagTwo = functions.https.onRequest(async (req, res) => {
  await corsManager(req, res, async () => {
    try {
      const userId = req.query.userId as string;
      const result = await checkFlag('flagTwo', userId);
      handleSnapShot(res, result);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:33:31