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
相关产品推荐
相关产品推荐

