Skip to content

docs: add TypeScript Query guide with info on lean() + transform() #15377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/layout.pug
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ html(lang='en')
- if (versions.currentVersion.listed !== versions.latestVersion.listed)
li.pure-menu-item
a.pure-menu-link(href=`${versions.latestVersion.path}/docs/index.html`) Version #{versions.latestVersion.listed}
each pastVersion in versions.pastVersions
each pastVersion in versions.pastVersions
li.pure-menu-item
a.pure-menu-link(href=`/docs/${pastVersion.path}/index.html`) Version #{pastVersion.listed}
li.pure-menu-item.search
Expand Down Expand Up @@ -105,6 +105,8 @@ html(lang='en')
a.pure-menu-link(href=`${versions.versionedPath}/docs/typescript/schemas.html`, class=outputUrl === `${versions.versionedPath}/docs/typescript/schemas.html` ? 'selected' : '') Schemas
li.pure-menu-item.sub-item
a.pure-menu-link(href=`${versions.versionedPath}/docs/typescript/statics-and-methods.html`, class=outputUrl === `${versions.versionedPath}/docs/typescript/statics-and-methods.html` ? 'selected' : '') Statics and Methods
li.pure-menu-item.sub-item
a.pure-menu-link(href=`${versions.versionedPath}/docs/typescript/queries.html`, class=outputUrl === `${versions.versionedPath}/docs/typescript/queries.html` ? 'selected' : '') Queries
li.pure-menu-item.sub-item
a.pure-menu-link(href=`${versions.versionedPath}/docs/typescript/query-helpers.html`, class=outputUrl === `${versions.versionedPath}/docs/typescript/query-helpers.html` ? 'selected' : '') Query Helpers
li.pure-menu-item.sub-item
Expand Down
41 changes: 41 additions & 0 deletions docs/typescript/queries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Queries in TypeScript

Mongoose's [Query class](../api/query.html) is a chainable query builder that represents a MongoDB query.
When you call `find()`, `findOne()`, `updateOne()`, `findOneAndUpdate()`, etc. on a model, Mongoose will return a Query instance.
Queries have a `.then()` function that returns a Promise, so you can use them with `await`.

In TypeScript, the Query class takes the following generic parameters:

```ts
class Query<
ResultType, // The type of the result of the query, like `DocType[]`
DocType, // The hydrated document type of the query's associated model
THelpers = {}, // Query helpers
RawDocType = unknown, // The "lean" document type of the query's associated model
QueryOp = 'find', // The operation that will be executed, like 'find', 'findOne', 'updateOne', etc.
TDocOverrides = Record<string, never> // Methods and virtuals on the hydrated document
>
```

## Using `lean()` in TypeScript

The [`lean()` method](../tutorials/lean.html) tells Mongoose to skip [hydrating](../api/model.html#model_Model-hydrate) the result documents, making queries faster and more memory efficient.
`lean()` comes with some caveats in TypeScript when working with the query `transform()` function.
In general, we recommend calling `lean()` before using the `transform()` function to ensure accurate types.

```ts
// Put `lean()` **before** `transform()` in TypeScript because `transform` modifies the query ResultType into a shape
// that `lean()` does not know how to handle.
const result = await ProjectModel
.find()
.lean()
.transform((docs) => new Map(docs.map((doc) => [doc._id.toString(), doc])));

// Do **not** do the following
const result = await ProjectModel
.find()
.transform((docs) => new Map(docs.map((doc) => [doc._id.toString(), doc])))
.lean();
```

In general, if you're having trouble with `lean()` inferring the correct type, you can try moving `lean()` earlier in the query chain.