首页 > 解决方案 > 如何使用 Typescript 扩展猫鼬查询类?

问题描述

我正在尝试使用 Mongoose、Redis 和 Typescript 实现缓存。我的cache.ts文件:

import mongoose, { model, Query } from "mongoose";
import redis from "redis";
//import { CacheOptions } from "../../types/mongoose";
type CacheOptions = { key?: string };
const client = redis.createClient();

const getCache = function (
    hashKey: string,
    key: string
): Promise<string | null> {
    return new Promise((res, rej) => {
        client.hget(hashKey, key, (err, val) => {
            if (err) rej(err);
            else res(val);
        });
    });
};

const exec = mongoose.Query.prototype.exec;

mongoose.Query.prototype.cache = function (options: CacheOptions = {}) {
    this.useCache = true;
    this.hashKey = JSON.stringify(options.key || "");

    return this; //make cache() chainable
};

mongoose.Query.prototype.exec = async function () {
    if (!this.useCache) {
        //NO CACHE
        return exec.apply(this);
    }
    const key = JSON.stringify({
        ...this.getQuery(),
        collection: this.model.collection.name,
    });

    const cacheValue = await getCache(this.hashKey, key);

    if (cacheValue) {
        console.log("DATA FROM CACHE");
        const doc = JSON.parse(cacheValue);

        //convert plain object to mongoose object
        return Array.isArray(doc)
            ? doc.map((d) => new this.model(d))
            : new this.model(doc);
    }

    const result = await exec.apply(this);

    client.hset(this.hashKey, key, JSON.stringify(result));
    return result;
};

/**
 *
 * @param hashKey hashkey to remove
 */
const clearHash = (hashKey: string) => {
    client.del(JSON.stringify(hashKey));
};

export { clearHash };

这是我在 types 文件夹下的类型声明文件:mongoose.d.ts

declare module "mongoose" {
    export interface Query<
        ResultType,
        DocType extends Document,
        THelpers = {}
    > {
        cache(): Query<T>;
        useCache: boolean;
        hashKey: string;
        model: Model<T>;
    }
}

VsCode IntelliSense 不会给出任何警告或错误。当我运行代码时,出现以下错误:

    TSError: ⨯ Unable to compile TypeScript:
src/services/product/product.controller.ts:92:67 - error TS2551: Property 'cache' does not exist on type 'Query<IProduct | null, IProduct, {}>'. Did you mean 'catch'?

92  const foundProduct = await Product.findOne({ slug }, { __v: 0 }).cache();

我不确定我是否正确定义了类型,但似乎 TypeScript 没有看到我的声明或其他内容。如果您有任何建议,我将不胜感激。

标签: node.jstypescriptmongoosecachingredis

解决方案


另一种选择是您可以做的是通过添加缓存覆盖 index.d.ts 中的 Query 类:任何


推荐阅读