Node.js MongoDB驱动中使用$inc动态键报错,如何解决?
解决MongoDB Node.js驱动$inc动态键的TypeScript类型错误
这个问题是TypeScript对MongoDB驱动的类型校验导致的——直接用动态键[productID]时,TypeScript会把$inc的对象推断为{ [x: string]: number },但驱动的类型系统期望它符合集合文档的结构定义或者明确的更新过滤器类型。
下面是几种可行的解决方法:
方法1:类型断言快速解决
直接把$inc的对象断言为any或者对应的更新过滤器类型,快速绕过类型检查:
await collection.updateOne( { _id: new ObjectId(userID) }, { $inc: { [productID]: 1 } as any }, { upsert: true } );
如果想更规范,可以先定义你的文档类型,再断言为UpdateFilter:
import { ObjectId, UpdateFilter } from 'mongodb'; // 定义集合的文档结构,允许动态产品ID作为键 interface UserProductCounts { _id: ObjectId; [productId: string]: number | ObjectId; // 产品ID对应数值,兼容_id的类型 } await collection.updateOne<UserProductCounts>( { _id: new ObjectId(userID) }, { $inc: { [productID]: 1 } as UpdateFilter<UserProductCounts> }, { upsert: true } );
方法2:提前构建更新对象并指定类型
先创建更新对象并明确它的类型,再传入updateOne:
import { UpdateFilter } from 'mongodb'; const update: UpdateFilter<UserProductCounts> = { $inc: { [productID]: 1 } }; await collection.updateOne({ _id: new ObjectId(userID) }, update, { upsert: true });
方法3:给集合指定带索引签名的类型
如果你的集合本身就是用来存储用户对不同产品的计数(动态键是常态),可以在获取集合时就指定带索引签名的文档类型,这样TypeScript会自动识别动态键的合法性:
const collection = db.collection<UserProductCounts>('user_product_counts'); // 此时直接用动态键不会报错 await collection.updateOne( { _id: new ObjectId(userID) }, { $inc: { [productID]: 1 } }, { upsert: true } );
内容的提问来源于stack exchange,提问作者Sylith
相关产品推荐
相关产品推荐

