ไทป์สคริปต์: อินสแตนซ์ของคลาสนามธรรม
ฉันมีคลาสนามธรรม Router:
export abstract class Router {
}
และอินเทอร์เฟซแบบนี้
interface IModule {
name: string;
forms: Array<IForm>,
route: typeof Router
}
ตอนนี้ฉันมีคลาสหนึ่งซึ่งดูเหมือนแบบนี้ และมีหลายคลาสอื่น ๆ ที่อิงตาม Router abstract
export class Module1 extends Router {
}
ตอนนี้ ฉันต้องการสร้างอินสแตนซ์ของเส้นทางแบบนี้:
let module: IModule = {
name: "My Module",
forms: [],
route: Module1
}
let router = new module.route();
// TS2511: Cannot create an instance of an abstract class.
โค้ดทำงานได้ดี และตัวอย่างของ router=new Module1() ถูกสร้างขึ้นอย่างถูกต้อง แต่เห็นได้ชัดว่าฉันไม่ได้เขียนมันอย่างถูกต้องใน Typescript เพราะฉันเห็น TS2511: Cannot create an instance of an abstract class. เมื่อทำการแปลงโค้ด
วิธีที่ถูกต้องในการกำหนดค่านี้คืออะไร?
คำตอบ #1
เมื่อคุณมีคลาสนามธรรม ตัวสร้างของมันสามารถเรียกใช้งานได้เฉพาะจากคลาสที่สืบทอดเท่านั้น เนื่องจากคลาสนี้เป็นนามธรรมและไม่ควรถูกสร้างอินสแตนซ์ ซึ่งสิ่งนี้ก็จะต่อเนื่องเมื่อคุณระบุชนิดบางอย่างเป็น typeof AbstractClass ตัวสร้างจะไม่สามารถเรียกใช้งานได้
วิธีแก้ปัญหาคือไม่ต้องใช้ typeof Router แต่ให้ใช้ลายเซ็นของตัวสร้าง (constructor) ที่คืนค่าเป็น Router
interface IModule {
name: string;
forms: Array<IForm>,
route: new () => Router
}
อีกวิธีหนึ่งหากคุณต้องการเข้าถึงเมทอดสถิตของ Router คือการสร้างอินเทอร์เฟซที่สืบทอดจาก typeof Router ซึ่งจะลบความเป็นนามธรรมของคอนสตรัคเตอร์ออก:
export abstract class Router {
static m(): void { console.log("Router"); }
}
type RouterClass = typeof Router;
interface RouterDerived extends RouterClass { }
interface IModule {
name: string;
route: RouterDerived
}
export class Module1 extends Router {
static m(): void { console.log("Module1"); }
}
let module: IModule = {
name: "My Module",
route: Module1
}
module.route.m();
let router = new module.route();
คำตอบ #2
หมายเหตุ ส่วนที่สองของคำตอบที่ยอมรับครอบคลุม:
ถ้าคุณต้องการเข้าถึงเมธอดสแตติกของ Router ...
วิธีแก้ปัญหาที่เสนอไม่ได้ผลจริง ๆ เพิ่งใช้เวลาพอสมควรในการพยายามหาวิธีแก้ไขเรื่องนี้ ดังนั้นคิดว่าควรเพิ่มว่า: วิธีทำสิ่งนี้คือ:
type RouterDerived = {new (): Router} & typeof Router;
สนามเด็กเล่นตัวอย่างเต็มรูปแบบ
