typescript - Mendapatkan nama kelas sebuah objek saat runtime
Apakah mungkin untuk mendapatkan nama kelas/tipe suatu objek saat runtime menggunakan TypeScript?
class MyClass{}
var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"
Jawaban #1
Jawaban sederhana :
class MyClass {}
const instance = new MyClass();
console.log(instance.constructor.name); // MyClass
console.log(MyClass.name); // MyClass
Namun: waspadalah bahwa nama tersebut kemungkinan akan berbeda saat menggunakan kode yang diminimalkan.
Jawaban #2
Solusiku bukan mengandalkan nama kelas. object.constructor.name bekerja secara teori. Tapi jika kamu menggunakan TypeScript di sesuatu seperti Ionic, begitu kamu masuk ke produksi, itu akan jadi bermasalah karena mode produksi Ionic meminifikasi kode Javascript. Jadi kelas-kelas akan dinamai seperti "a" dan "e."
Yang akhirnya saya lakukan adalah memiliki kelas typeName di semua objek saya yang mana konstruktor menetapkan nama kelas ke dalamnya. Jadi:
export class Person {
id: number;
name: string;
typeName: string;
constructor() {
typeName = "Person";
}
Ya, itu sebenarnya bukan yang diminta. Tapi menggunakan constructor.name pada sesuatu yang mungkin saja akan diminimalkan nantinya sungguh seperti mengundang sakit kepala.
Jawaban #3
Saya tahu saya terlambat ke pesta, tapi saya menemukan bahwa ini juga berhasil.
var constructorString: string = this.constructor.toString();
var className: string = constructorString.match(/\w+/g)[1];
Sebagai alternatif...
var className: string = this.constructor.toString().match(/\w+/g)[1];
Kode di atas mengambil seluruh kode konstruktor sebagai string dan menerapkan regex untuk mendapatkan semua 'kata'. Kata pertama seharusnya 'function' dan kata kedua seharusnya nama kelas.
Semoga ini membantu.
Jawaban #4
Anda perlu terlebih dahulu mengubah instansi menjadi any karena definisi tipe Function tidak memiliki properti name.
class MyClass {
getName() {
return (<any>this).constructor.name;
// OR return (this as any).constructor.name;
}
}
// From outside the class:
var className = (<any>new MyClass()).constructor.name;
// OR var className = (new MyClass() as any).constructor.name;
console.log(className); // Should output "MyClass"
// From inside the class:
var instance = new MyClass();
console.log(instance.getName()); // Should output "MyClass"
Perbarui :
Dengan TypeScript 2.4 (dan mungkin versi sebelumnya) kode bisa menjadi lebih bersih:
class MyClass {
getName() {
return this.constructor.name;
}
}
// From outside the class:
var className = (new MyClass).constructor.name;
console.log(className); // Should output "MyClass"
// From inside the class:
var instance = new MyClass();
console.log(instance.getName()); // Should output "MyClass"
Jawaban #5
Solusi menggunakan Dekorator yang bertahan dari minifikasi/uglifikasi
Kami menggunakan pembuatan kode untuk mendekorasi kelas Entity kami dengan metadata seperti berikut:
@name('Customer')
export class Customer {
public custId: string;
public name: string;
}
Kemudian konsumsi dengan bantuan berikut:
export const nameKey = Symbol('name');
/**
* To perserve class name though mangling.
* @example
* @name('Customer')
* class Customer {}
* @param className
*/
export function name(className: string): ClassDecorator {
return (Reflect as any).metadata(nameKey, className);
}
/**
* @example
* const type = Customer;
* getName(type); // 'Customer'
* @param type
*/
export function getName(type: Function): string {
return (Reflect as any).getMetadata(nameKey, type);
}
/**
* @example
* const instance = new Customer();
* getInstanceName(instance); // 'Customer'
* @param instance
*/
export function getInstanceName(instance: Object): string {
return (Reflect as any).getMetadata(nameKey, instance.constructor);
}
Info tambahan:
- Anda mungkin perlu menginstal
reflect-metadata reflect-metadataadalah pollyfill yang ditulis oleh anggota TypeScript untuk API Refleksi ES7 yang diusulkan- Usulan untuk dekorator di JS dapat dilacak di sini
Jawaban #6
Lihat pertanyaan ini.
Karena TypeScript dikompilasi menjadi JavaScript, saat runtime Anda menjalankan JavaScript, jadi aturan yang sama akan berlaku.
