无法在 mongoose 中使用通用模型:“x”类型的参数不可分配给 MongooseFilterQuery 类型的参数

Posted

技术标签:

【中文标题】无法在 mongoose 中使用通用模型:“x”类型的参数不可分配给 MongooseFilterQuery 类型的参数【英文标题】:Cannot use generic model in mongoose: Argument of type 'x' is not assignable to parameter of type MongooseFilterQuery 【发布时间】:2020-08-09 22:54:11 【问题描述】:

我正在尝试将通用 Mongoose 模型作为参数传递给函数。

import mongoose,  Document, Model, Schema  from 'mongoose';

interface User 
    name: string;
    age: number;
    favouriteAnimal: string;


const UserSchema = new Schema(
    name: String,
    age: Number,
    favouriteAnimal: String,
);

const UserModel = mongoose.model<User & Document>('User', UserSchema);

function doSomething() 
    return UserModel.findOne( user: 'john' ); // This is fine.


async function doSomethingGeneric<T extends User & Document>(model: Model<T>, key: keyof T) 
    const user = await model.findOne( user: 'john' ); // Compiler errors on this line.
    return user![key];

这是编译器的错误输出:

error TS2345: Argument of type ' user: string; ' is not assignable to parameter of type 'MongooseFilterQuery<Pick<T, Exclude<keyof T, "toString" | "removeListener" | "off" | "update" | "invalidate" | "increment" | "model" | "$isDeleted" | "remove" | "save" | "__v" | "$isDefault" | "$session" | ... 47 more ... | "modelName">>>'.

Type ' user: string; ' is not assignable to type ' [P in keyof Pick<T, Exclude<keyof T, "toString" | "removeListener" | "off" | "update" | "invalidate" | "increment" | "model" | "$isDeleted" | "remove" | "save" | "__v" | "$isDefault" | "$session" | ... 47 more ... | "modelName">>]?: (P extends "_id" ? [...] extends [...] ? Condition<...> : Condition<...> : [...] e...'.

23    const user = await model.findOne( user: 'john' );

UserModel 的类型是mongoose.Model&lt;User &amp; mongoose.Document, &gt;,所以我希望泛型满足与非泛型方法相同的类型约束。我哪里错了?

编辑:我有recreated the issue in the TS playground,所以你可以直接看到它。

【问题讨论】:

您能否发布完整的 .ts 文件? @Valijon 这是一个人为的例子来演示这个问题;它是整个 .ts 文件。如果不发布我的实际代码,我将无法分享更多内容,但这会使事情变得相当复杂,因为它包含很多根本不相关的东西。但是,如果有不清楚的具体内容,我很乐意澄清我的问题/示例? 检查此解决方案是否解决了问题async function doSomethingGeneric&lt;T extends User &amp; Document&gt;(model: mongoose.Model&lt;T&gt;, key: keyof T, query: any) const user = await model.findOne(query); return user![key]; 【参考方案1】:

这已被确认为 Typescript 错误:https://github.com/DefinitelyTyped/DefinitelyTyped/issues/39358

一种可能的解决方法是将查询对象手动转换为正确的类型:

async function doSomethingGeneric<T extends User & Document>(model: Model<T>, key: keyof T) 
    const user = await model.findOne( user: 'john'  as FilterQuery<T>);
    return user![key];                    /* add this ^^^^^^^^^^^^^^^^^ */

【讨论】:

以上是关于无法在 mongoose 中使用通用模型:“x”类型的参数不可分配给 MongooseFilterQuery 类型的参数的主要内容,如果未能解决你的问题,请参考以下文章

在 Mongoose 中保存模型无法保存嵌套组件

无法使用 $pull (Mongoose) 为用户模型删除数组中的对象

Nest.js 在单元测试中无法解析 Mongoose 模型依赖

使用 Mongoose.js 保存模型时,为啥会出现“无法调用未定义的 doValidate”?

使用 Mongoose.js 保存模型时,为啥会出现“无法调用未定义的 doValidate”?

无法在关系 nestjs/mongoose 上查询条件