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

扩展Mongoose查询缓存功能:JS转TS遇类型错误求助

Mongoose Query缓存扩展的TypeScript错误修复

错误1:All declarations of 'Query' must have identical type parameters.

Mongoose原生Query接口包含多个泛型参数,自定义扩展时必须与原接口的泛型签名完全匹配,不能仅声明单个泛型参数。

修复方式:扩展Query接口时使用完整的泛型参数列表,返回类型用this保持链式调用的泛型一致性:

declare module 'mongoose' {
  interface Query<ResultType, DocType, THelpers = {}, RawDocType = DocType, QueryOp = "find", DocTypeFields = Required<DocType>> {
    useCache?: boolean;
    hashKey?: string;
    cache(options?: { key?: unknown }): this;
  }
}

错误2:Argument of type 'IArguments' is not assignable to parameter of type '[]'

TypeScript对arguments对象的类型检查严格,直接传递会触发类型不匹配报错。可以改用剩余参数接收exec的入参,替代arguments。

修复方式:在exec方法定义中使用剩余参数,调用原生exec时直接传递该参数数组:

Query.prototype.exec = async function (...args: Parameters<typeof exec>): Promise<any> {
  if (!this.useCache) {
    return exec.apply(this, args);
  }
  // 后续代码中统一用args代替arguments
}

错误3:Property 'mongooseCollection' does not exist on type 'Query<...>'

mongooseCollection是Mongoose内部未对外暴露的属性,TypeScript类型定义中未包含该字段。可以通过公开的this.model.collection.name获取集合名称。

修复方式:替换原集合名称获取代码:

const key = JSON.stringify(Object.assign({}, this.getFilter(), {
  collection: this.model.collection.name,
}));

完整修复后的TypeScript代码

import mongoose, { Query } from 'mongoose';
import RedisClient from './redisClient';

// 扩展Mongoose Query接口,匹配完整泛型参数
declare module 'mongoose' {
  interface Query<ResultType, DocType, THelpers = {}, RawDocType = DocType, QueryOp = "find", DocTypeFields = Required<DocType>> {
    useCache?: boolean;
    hashKey?: string;
    cache(options?: { key?: unknown }): this;
  }
}

const exec = Query.prototype.exec;

// 实现cache方法,返回this保持链式调用
Query.prototype.cache = function (options = {}): this {
  this.useCache = true;
  this.hashKey = JSON.stringify(options.key || '');
  return this;
};

// 重写exec方法,使用剩余参数避免arguments类型问题
Query.prototype.exec = async function (...args: Parameters<typeof exec>): Promise<any> {
  if (!this.useCache) {
    return exec.apply(this, args);
  }

  const key = JSON.stringify(Object.assign({}, this.getFilter(), {
    collection: this.model.collection.name,
  }));

  const cachedValue = await RedisClient.getHCache(this.hashKey, key);

  if (cachedValue) {
    const doc = JSON.parse(cachedValue);
    return Array.isArray(doc)
      ? doc.map((d: any) => new this.model(d))
      : new this.model(doc);
  }

  const result = await exec.apply(this, args);
  await RedisClient.setHCache(this.hashKey, key, JSON.stringify(result));

  return result;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:45:41