From cc88cd491064c4b89df8dd6212e454a33c70f92d Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 28 Apr 2025 14:06:06 -0400 Subject: [PATCH] docs: add TypeScript Query guide with info on `lean()` + `transform()` Fix #15311 --- docs/layout.pug | 4 +++- docs/typescript/queries.md | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 docs/typescript/queries.md diff --git a/docs/layout.pug b/docs/layout.pug index 16dd2cf9257..886dbbd3b5c 100644 --- a/docs/layout.pug +++ b/docs/layout.pug @@ -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 @@ -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 diff --git a/docs/typescript/queries.md b/docs/typescript/queries.md new file mode 100644 index 00000000000..317c33dc98a --- /dev/null +++ b/docs/typescript/queries.md @@ -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 // 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.