การพิจารณาตนเอง - TypeScript: การดึงคลาส/คอนสตรัคเตอร์ของวัตถุในขณะรันไทม์
เพื่อจุดประสงค์ในการดีบัก ฉันต้องการให้เมธอด toString() ของคลาสนามธรรมแสดงว่าตัวอย่างนั้นเป็นของซับคลาสใดจริง ๆ
abstract FrameModel {
...
public toString() {
var classOfThis = ?????;
return `FrameModel<${classOfThis}>#${this.vertexId}`;
}
}
นอกจากนี้จะดีถ้าฉันสามารถใช้คลาสนั้นใน TypeScript เพื่อเข้าถึงสมาชิก static; กล่าวอีกนัยหนึ่ง ถ้าฉันได้ฟังก์ชันตัวสร้าง JavaScript ที่ TypeScript ใส่ฟิลด์ static
ฉันได้พยายาม
var classOfThis = Object.getPrototypeOf(this).constructor;
แต่นั่นไม่ใช่สิ่งนั้น :)
คำตอบ #1
การใช้ Object.getPrototypeOf(this).constructor นั้นใช้งานได้จริง:
type AConstructor = {
new(): A;
name: string;
}
abstract class A {
toString(): string {
return `class: ${ (Object.getPrototypeOf(this).constructor as AConstructor).name }`;
}
}
class B extends A {}
class C extends A {}
let b = new B();
console.log(b.toString()); // class: B
let c = new C();
console.log(c.toString()); // class: C
(โค้ดในสนามเด็กเล่น)
ฉันไม่แน่ใจว่าทำไมมันถึงใช้ไม่ได้กับคุณ ฉันจะต้องดูโค้ดของคุณเพิ่มเติม
ในกรณีใด ๆ คุณก็สามารถใช้ได้เช่นกัน: this.constructor:
toString(): string {
return `class: ${ (this.constructor as AConstructor).name }`;
}
คำตอบ #2
ฉันคิดวิธีนี้ออกมา ซึ่งสามารถสรุปประเภทที่ถูกต้องสำหรับ Intellisense เป็นต้น:
interface ConstructorOf<T> {
new(): T;
}
class Animal {
get cls(): ConstructorOf<this> {
return this.constructor as any;
}
clone() {
const ret = new this.cls;
return ret;
}
}
class Mammal extends Animal {
// Nothing yet.
}
const animal1 = new Animal;
const animal2 = animal1.clone();
const mammal1 = new Mammal;
const mammal2 = mammal1.clone();
TS PlayGround: https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgMIHsQGcxQK4JjpQDyMAPACoB8yA3gLABQyyIEA7gBQCUAXMkoBuZgF9mCADZwsWZAEEQwALZxJ9ZqwDmEMMilZeAjNlwEipCmAAWwLLUYtWyKLrxQQyG3YB0CTDj4hMTIMqEgAJ4iTuJOUpgQvPSsms7+pi66yAC8bJxetlh+kljRzplg7p6uYGXIsbFSMnIAsnDKquoQAB6QIAAmcooqahpOAPTjyABy6N4gWsgRuj5iEgF6cEqdAIw5eRwK22rR6TjhI5IATPtblzvFCbynG8iqHWp7ueyHbR+SLwy706N1ywM+j3Yz2YQA
