TypeScript の静的メソッドとメソッド

インスタンス メソッドと静的関数を Mongoose モデルに定義できます。追加設定を少し加えるだけで、TypeScript でメソッドと静的方法も登録できます。

メソッド

TypeScript で インスタンス メソッド を定義するには、インスタンス メソッドを表す新しいインターフェイスを作成します。そのインターフェイスを、Schema コンストラクタへの第 3 のジェネリック パラメータ Model への第 3 のジェネリック パラメータとして渡す必要があります。以下に示すようにします。

import { Model, Schema, model } from 'mongoose';

interface IUser {
  firstName: string;
  lastName: string;
}

// Put all user instance methods in this interface:
interface IUserMethods {
  fullName(): string;
}

// Create a new Model type that knows about IUserMethods...
type UserModel = Model<IUser, {}, IUserMethods>;

// And a schema that knows about IUserMethods
const schema = new Schema<IUser, UserModel, IUserMethods>({
  firstName: { type: String, required: true },
  lastName: { type: String, required: true }
});
schema.method('fullName', function fullName() {
  return this.firstName + ' ' + this.lastName;
});

const User = model<IUser, UserModel>('User', schema);

const user = new User({ firstName: 'Jean-Luc', lastName: 'Picard' });
const fullName: string = user.fullName(); // 'Jean-Luc Picard'

静的

Mongoose モデル は、静的 メソッド用の明示的なジェネリック パラメータは ありません。モデルに静的メソッドがある場合は、以下に示すように、Mongoose の Model インターフェイスを 継承 するインターフェイスを作成することをお勧めします。

import { Model, Schema, model } from 'mongoose';

interface IUser {
  name: string;
}

interface UserModel extends Model<IUser> {
  myStaticMethod(): number;
}

const schema = new Schema<IUser, UserModel>({ name: String });
schema.static('myStaticMethod', function myStaticMethod() {
  return 42;
});

const User = model<IUser, UserModel>('User', schema);

const answer: number = User.myStaticMethod(); // 42

Mongoose は、スキーマ オプションで提供されるようになり、自動的に型付けされた静的関数をサポートします。静的関数は、次のように定義できます。

import { Schema, model } from 'mongoose';

const schema = new Schema(
  { name: String },
  {
    statics: {
      myStaticMethod() {
        return 42;
      }
    }
  }
);

const User = model('User', schema);

const answer = User.myStaticMethod(); // 42

メソッドと静的メソッドの両方

以下は、メソッドと静的メソッドの両方を持つモデルを定義する方法です。

import { Model, Schema, HydratedDocument, model } from 'mongoose';

interface IUser {
  firstName: string;
  lastName: string;
}

interface IUserMethods {
  fullName(): string;
}

interface UserModel extends Model<IUser, {}, IUserMethods> {
  createWithFullName(name: string): Promise<HydratedDocument<IUser, IUserMethods>>;
}

const schema = new Schema<IUser, UserModel, IUserMethods>({
  firstName: { type: String, required: true },
  lastName: { type: String, required: true }
});
schema.static('createWithFullName', function createWithFullName(name: string) {
  const [firstName, lastName] = name.split(' ');
  return this.create({ firstName, lastName });
});
schema.method('fullName', function fullName(): string {
  return this.firstName + ' ' + this.lastName;
});

const User = model<IUser, UserModel>('User', schema);

User.createWithFullName('Jean-Luc Picard').then(doc => {
  console.log(doc.firstName); // 'Jean-Luc'
  doc.fullName(); // 'Jean-Luc Picard'
});