TypeScript - ใช้คลาสเป็นทั้งคอนสตรัคเตอร์และประเภท
ฉันมีคลาสที่ชื่อว่า Model ซึ่งห่อหุ้มคลาส schema อย่างเช่น "Person" และสามารถสร้างอินสแตนซ์ได้สำเร็จดังนี้:
const people = new Model<Person>(Person, db);
DB เป็นการสร้างนามธรรมให้กับฐานข้อมูลและอนุญาตให้โมเดลสื่อสารกับฐานข้อมูลโดยไม่ต้องรู้รายละเอียดของ DB ... มันอาจจะไม่สำคัญมากสำหรับคำถามนี้ แต่ฉันหยิบขึ้นมาพูดเพราะมันดูสำคัญอย่างยิ่ง
ความซ้ำซ้อนของการส่งคลาส Person สองครั้งนั้นน่ารำคาญและฉันคิดว่าฉันอาจจะสามารถสร้างเมธอดสแตติกจาก Model ที่เรียกว่า create() ซึ่งมีลักษณะดังนี้:
public static create(schema: new () => any, options: IModelOptions = {}) {
const schemaClass = new schema();
const db = options.db || Model.defaultDb;
const logger = options.logger || baseLogger;
const model = new Model<typeof schema>(schema, db, logger);
return model;
}
ซึ่งฉันสามารถสร้างอินสแตนซ์ได้อย่างง่ายดายด้วย:
const people = Model.create(Person, { db });
นี่เกือบจะดูเหมือนว่ามันได้ผล แต่ดูเหมือนว่า Typescript จะเข้าใจประเภททั่วไปที่ใช้สำหรับ Model ผิดเล็กน้อย ฉันกำลังเข้าใจผิดอยู่หรือไม่? มีวิธีที่จะทำในสิ่งที่ฉันต้องการทำหรือไม่? ถ้าใช่ ฉันทำอะไรผิด?
เพื่อให้รายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่ ไม่ ทำงาน ... ผมพบว่าข้อมูลประเภททั่วไปที่ส่งเข้ามาเป็น "T":
export default class Model<T extends BaseSchema> { ... }
ไม่ได้พิมพ์สิ่งต่าง ๆ อย่างถูกต้อง ดังนั้นตัวอย่างเช่น ส่วนติดต่อสาธารณะหลายส่วนของ Model จำกัดข้อมูลนำเข้าให้เป็นชนิด <T> แต่แทนที่จะเป็น "Person" กลับถูกแก้ไขเป็นฟังก์ชันตัวสร้างสำหรับ Person: new() => any ซึ่งดูเหมือนไม่จำกัดอะไรเลย
คำตอบ #1
คุณควรทำให้ create เป็นแบบทั่วไปด้วยเช่นกัน และให้คอมไพเลอร์คาดเดาประเภทอินสแตนซ์ตามประเภทการคืนค่าของคอนสตรัคเตอร์ ตอนนี้คุณกำลังสร้าง Model<typeof Person> โดยที่คุณต้องการ Model<Person>:
class Model<T> {
public constructor(schema: T) {}
public static create<T>(schema: new () => T) {
const schemaClass = new schema();
const model = new Model<T>(schemaClass);
return model;
}
}
class Person {}
let personModel = Model.create(Person) // will be Model<Person>
