From c6b9b5f2680d0b07f82e28af025e97ef8f5b710b Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 2 Jan 2023 14:24:20 -0500 Subject: [PATCH] docs(typescript): explain that virtuals inferred from schema only show up on Model, not raw document type Fix #12684 --- docs/typescript/virtuals.md | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/typescript/virtuals.md b/docs/typescript/virtuals.md index 258cc59034e..dda7cd729fe 100644 --- a/docs/typescript/virtuals.md +++ b/docs/typescript/virtuals.md @@ -16,9 +16,9 @@ const schema = new Schema( lastName: String, }, { - virtuals:{ - fullName:{ - get(){ + virtuals: { + fullName: { + get() { return `${this.firstName} ${this.lastName}`; } // virtual setter and options can be defined here as well. @@ -28,7 +28,32 @@ const schema = new Schema( ); ``` +Note that Mongoose does **not** include virtuals in the returned type from `InferSchemaType`. +That is because `InferSchemaType` returns the "raw" document interface, which represents the structure of the data stored in MongoDB. + +```ts +type User = InferSchemaType; + +const user: User = {}; +// Property 'fullName' does not exist on type '{ firstName?: string | undefined; ... }'. +user.fullName; +``` + +However, Mongoose **does** add the virtuals to the model type. + +```ts +const UserModel = model('User', schema); + +const user = new UserModel({ firstName: 'foo' }); +// Works +user.fullName; + +// Here's how to get the hydrated document type +type UserDocument = ReturnType<(typeof UserModel)['hydrate']>; +``` + ### Set virtuals type manually: + You shouldn't define virtuals in your TypeScript [document interface](../typescript.html). Instead, you should define a separate interface for your virtuals, and pass this interface to `Model` and `Schema`.