From cdfae32b423bbe6319414515f17909218e79ad16 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 2 Aug 2023 15:22:12 -0400 Subject: [PATCH] docs(typescript): highlight auto type inference for methods and statics, add info on using methods with generics Fix #12942 --- docs/layout.pug | 2 +- docs/typescript/statics.md | 67 +++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/docs/layout.pug b/docs/layout.pug index a57a66bff87..98b1a7166f4 100644 --- a/docs/layout.pug +++ b/docs/layout.pug @@ -104,7 +104,7 @@ html(lang='en') li.pure-menu-item.sub-item 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 + 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/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/statics.md b/docs/typescript/statics.md index 81f04423613..4c6f94bfc1c 100644 --- a/docs/typescript/statics.md +++ b/docs/typescript/statics.md @@ -1,5 +1,37 @@ # Statics in TypeScript +To use Mongoose's automatic type inference to define types for your [statics](guide.html#statics) and [methods](guide.html#methods), you should define your methods and statics using the `methods` and `statics` schema options as follows. +Do **not** use `Schema.prototype.method()` and `Schema.prototype.static()`. + +```typescript +const userSchema = new mongoose.Schema( + { name: { type: String, required: true } }, + { + methods: { + updateName(name: string) { + this.name = name; + return this.save(); + } + }, + statics: { + createWithName(name: string) { + return this.create({ name }); + } + } + } +); +const UserModel = mongoose.model('User', userSchema); + +const doc = new UserModel({ name: 'test' }); +// Compiles correctly +doc.updateName('foo'); +// Compiles correctly +UserModel.createWithName('bar'); +``` + +### With Generics + +While we recommend using Mongoose's automatic type inference where possible, you may need to override method and static types using generic parameters. Mongoose [models](../models.html) do **not** have an explicit generic parameter for [statics](guide.html#statics). If your model has statics, we recommend creating an interface that [extends](https://www.typescriptlang.org/docs/handbook/interfaces.html) Mongoose's `Model` interface as shown below. @@ -24,24 +56,27 @@ const User = model('User', schema); const answer: number = User.myStaticMethod(); // 42 ``` -Mongoose does support auto typed static functions that it are supplied in schema options. -Static functions can be defined by: +You should pass methods as the 3rd generic param to the `Schema` constructor as follows. ```typescript -import { Schema, model } from 'mongoose'; +import { Model, Schema, model } from 'mongoose'; -const schema = new Schema( - { name: String }, - { - statics: { - myStaticMethod() { - return 42; - } - } - } -); +interface IUser { + name: string; +} -const User = model('User', schema); +interface UserMethods { + updateName(name: string): Promise; +} -const answer = User.myStaticMethod(); // 42 -``` +const schema = new Schema, UserMethods>({ name: String }); +schema.method('updateName', function updateName(name) { + this.name = name; + return this.save(); +}); + +const User = model('User', schema); +const doc = new User({ name: 'test' }); +// Compiles correctly +doc.updateName('foo'); +``` \ No newline at end of file