Skip to content

TypeScript: Query Helper types do not work on findOneAndUpdate() #10658

Closed
@Davies-Owen

Description

@Davies-Owen

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
TypeScript does not recognize my custom Query Helpers on findOneAndUpdate and findByIdAndUpdate queries.

If the current behavior is a bug, please provide the steps to reproduce.

Adapted from the example here: https://mongoosejs.com/docs/typescript/query-helpers.html.
I am trying to make a query helper to lean the results of a query with virtuals. The query helper works correctly for other find queries.

import { Document, Model, Query, Schema, connect, model } from 'mongoose';

interface Project {
  name: string;
  stars: number;
}

const schema = new Schema<Project>({
  name: { type: String, required: true },
  stars: { type: Number, required: true }
});
// Query helpers should return `Query<any, Document<DocType>> & ProjectQueryHelpers`
// to enable chaining.
interface ProjectQueryHelpers {
  leaned(): Query<any, Document<Project>> & ProjectQueryHelpers;
}
schema.query.leaned = function(): Query<any, Document<Project>> & ProjectQueryHelpers {
  return this.lean({ defaults: true, virtuals: true });
};

// 2nd param to `model()` is the Model class to return.
const ProjectModel = model<Project, Model<Project, ProjectQueryHelpers>>('Project', schema);

run().catch(err => console.log(err));

async function run(): Promise<void> {
  await connect('mongodb://localhost:27017/test');

  // TS error: Property 'leaned' does not exist on type 'Query<Project, Document<any, any, Project> & Project, Project, Document<any, any, Project> & Project>'.ts(2339)
  await ProjectModel.findOneAndUpdate({name: 'mongoose'}, {stars: 1}).where('stars').gt(1000).leaned();
}

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "declaration": true,
    "experimentalDecorators": true,
    "incremental": true,
    "jsx": "react",
    "lib": ["ES2020"],
    "module": "commonjs",
    "moduleResolution": "node",
    "pretty": true,
    "removeComments": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "target": "ES2020",
    "traceResolution": false
  }
  "include": ["src"]
}

What is the expected behavior?
TypeScript should recognize the query helper on findOneAndUpdate and related queries.
I believe this is happening because findOneAndUpdate and fingByIdAndUpdate return the Query type instead of the QueryWithHelpers type that other find queries return:

findByIdAndUpdate(id: mongodb.ObjectId | any, update: UpdateQuery<T>, callback: (err: CallbackError, doc: T | null, res: any) => void): Query<T | null, EnforceDocument<T, TMethods>, T>;

I apologize if this is intended behavior that I'm just not understanding.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Node.js v14.16.1
TypeScript 4.2.4
Mongoose 6.0.3
MongoDB 4.1.1

Thanks in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    typescriptTypes or Types-test related issue / Pull Request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions