TypeScript นี่ประโยชน์ของมันก็เยอะ แต่การจะเอามาใช้กับโลกของ JavaScript ก็มีความท้าทายอยู่ไม่น้อยเลย โดยเฉพาะสำหรับคนที่ชินกับ JavaScript เพียวๆ มาแบบพล
ในที่นี้จะมาว่าเรื่องของ Mongoose ในการติดต่อฐานข้อมูล MongoDB ในคอร์ส Mongoose for Web Developer กัน
ว่าด้วยเรื่อง Mongoose.methods
คือในตัว Schema ของ Mongoose มันสามารถทำให้เรากำหนด method เอาไว้ใช้งานในตอนที่สร้างเป็น Model ออกมาได้ โดยใช้วิธีการแบบด้านล่าง
// อันนี้ Schema ของ User
UserSchema.methods.checkPassword = async function (password: string) {
// ของจริงไม่ทำอย่างนี้นะ แต่ให้สังเกตว่า การใช้ Schema.methods จะทำให้ตัว function สามารถเข้าถึง field ต่างๆ ได้
// เหมือนกับเขียนเรียกใช้ property ของ Class ในการเขียนโปรแกรมแบบ OOP
return this.password == passsword;
};
พอทำแบบนี้ เราก็สามารถใช้ method ที่สร้างไว้มาใช้งาน ได้ ในฐานะ method ของ Model
const user = mongoose.model("User", UserSchema)
user.findByUserName('nextflow')
สะดวกใช่ไหมล่ะ
แต่พอเขียนแบบ TypeScript แล้ว มันไม่ขึ้น มันหาไม่เจออ่ะ
ทีนี้เราจะพอทราบมาจากในการเรียนมาว่า เฮ้ย ถ้าเราอยากได้คุณสมบัติ Type Safe ไม่ดึงค่ากันมั่วๆ แบบวินาศสันตะโรเนี่ย เราจะเขียนแบบ TypeScript ใช่ไหมล่ะ?
แต่พอเขียนแบบ TypeScript มันก็ต้องกำหนดเป็น Interface ทีนี้เจ้า methods ของ Schema ก็ต้องมีการกำหนดเหมือนกันครับ
import { Schema, Document, model } from "mongoose";
// อันนี้แบบปกติ
interface IUser {
username: string;
hashedPassword: string;
}
// แต่เราสร้าง interface ขึ้นมาอีกอันโดยเฉพาะ
// ให้สังเกตว่าเรา extends ทั้ง interface ปกติของเรา และ Document class ของ mongoose
interface IUserDocument extends IUser, Document {
// สังเกตว่าเรากำหนด method, parameter และ return type ตรงกับที่กำหนดให้กับ Schema.methods
checkPassword: (password: string) => Promise<boolean>;
}
// อันนี้ Schema.methods ที่เรากำหนดเพื่อเอาไว้ใช้งาน
UserSchema.methods.checkPassword = async function (password: string) {
return this.password == passsword;
}
// สุดท้ายล้ะ จะเห็นว่าเรากำหนด type เป็น IUserDocument แทน IUser แบบเพียวๆ ซึ่งวิธีนี้จะทำให้เราสามารถเรียกใช้ methods ที่สร้างไว้ได้ เย้
const User = mongoose.model<IUserDocument>("User", UserSchema);
จริงๆ จะมีวิธีการกำหนด interface สำหรับ Schema.statics อีกนะ อันนี้ไปดูที่ต้นทางได้
อ้างอิง – [Typescript] mongoose methods, statics | millo’s tech blog (millo-l.github.io)