Typescript Firebase云函数类型脚本错误“;并非所有代码路径都返回一个值";
我正在使用firebase云功能和firestore事务来减少基于购买的产品的可用数量。部署时,它返回错误“error TS7030:并非所有代码路径都返回值” 这是密码Typescript Firebase云函数类型脚本错误“;并非所有代码路径都返回一个值";,typescript,google-cloud-firestore,google-cloud-functions,tslint,Typescript,Google Cloud Firestore,Google Cloud Functions,Tslint,我正在使用firebase云功能和firestore事务来减少基于购买的产品的可用数量。部署时,它返回错误“error TS7030:并非所有代码路径都返回值” 这是密码 import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; admin.initializeApp(); const db = admin.firestore() exports.newOrder =
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
const db = admin.firestore()
exports.newOrder = functions.firestore
.document('orders/{orderId}')
.onCreate(async (snap, context) => {
try {
const data = snap.data();
if (data === undefined) return null
const itemList = data.list as Array<any>
const productId: Set<string> = new Set<string>();
itemList.forEach((item) => {
productId.add(item.id)
})
return db.runTransaction(async t => {
const promises: Promise<admin.firestore.DocumentSnapshot>[] = []
productId.forEach(i => {
const p = admin.firestore().doc('Products/' + i).get()
promises.push(p)
})
const docs=await Promise.all(promises)
docs.forEach(doc => {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
})
itemList.forEach(j => {
if (j.variation === '-') {
const available = docs[j.id].get('available')
const needed = j.quantity
if (available < needed) {
return Promise.reject("Product out of stock")
}
}
else {
const variations = docs[j.id].get('variation') as Map<string, any>
for (const i in variations.keys) {
if (i === j.variation) {
const needed = j.quantity
const available = docs[j.id].get('variation').get(i).get('quantity')
if (available < needed) {
return Promise.reject("Product out of stock")
}
}
}
}
})
itemList.forEach(j => {
if (j.variation === '-') {
const available = docs[j.id].get('available')
const needed = j.quantity
t.update(db.doc('Products/' + j.id), { 'available': available - needed })
}
else {
const variations = docs[j.id].get('variation') as Map<string, any>
for (const i in variations.keys) {
if (i === j.variation) {
const needed = j.quantity
const available = docs[j.id].get('variation').get(i).get('quantity')
t.update(db.doc('Products/' + j.id), { [`variation.${i}.quantity`]: available - needed })
}
}
}
})
return Promise.resolve("Product quantity updated")
})
}
catch (error) {
console.log(`error ${error}`)
return null
}
});
如何解决错误
错误中提到的2个循环检查产品是否被删除以及产品是否缺货。如果它满足条件,我想退出函数。请帮助我。错误消息告诉您,有些函数在所有情况下都不会返回值。它甚至可以告诉你哪些函数违反了这个要求。以下是第一个错误:
src/index.ts:30:30 - error TS7030: Not all code paths return a value.
30 docs.forEach(doc => {
~~~~~~~~
它告诉您传递给forEach的函数有问题
下面是函数:
docs.forEach(doc => {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
})
请注意,当doc.exists
为true时,函数不会返回值。如果您不关心这种情况,只需返回null:
docs.forEach(doc => {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
else {
return null
}
})
现在错误消失了,因为所有代码路径都返回一个值。您可以对另一个错误应用相同的逻辑。问题比看起来更严重。您可能误解了
return
语句在forEach
中的作用。代码的结构就像假设检查doc.exists
中的任何一个是否为false,如果为false,则提前返回,但这样写的话,它将从迭代回调返回。。由于forEachforEach
不使用回调返回值,因此承诺拒绝仍然未处理
实现这一结果的适当方法如下:
1) 只需直接检查您需要检查的内容:
if (docs.findIndex(doc => !doc.exists) !== -1) {
return Promise.reject("Product deleted");
}
2) 使用循环的中的.或
中的.代替
forEach:
for (doc of docs) {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
}
3) 使用映射
和等待
结果(不推荐,因为您实际上不需要映射):
请注意,在这种情况下,结果数组中任何被拒绝的承诺都会触发外部承诺的拒绝
旁注:您永远不需要显式的
Promise.reject()
调用。由于您的函数是异步的,您可以简单地抛出将用作错误的东西-这将转化为承诺拒绝。这是Typescript强加愚蠢约定的一个很好的例子。
当没有显式返回语句时,JavaScript函数默认输出未定义的
。我建议在tsconfig.json
中禁用返回检查:
{
“编译器选项”:{
“noImplicitReturns”:false,
}
}
for (doc of docs) {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
}
await Promise.all(docs.map(doc => {
if (!doc.exists) {
return Promise.reject("Product deleted")
}
return null
})