457 Stimmen

Abrufen des Klassennamens eines Objekts zur Laufzeit

Ist es möglich, den Klassen-/Typnamen eines Objekts zur Laufzeit mit TypeScript zu erhalten?

class MyClass{}

var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"

741voto

Mikael Couzic Punkte 10957

Einfache Antwort:

class MyClass {}

const instance = new MyClass();

console.log(instance.constructor.name); // MyClass
console.log(MyClass.name);              // MyClass

Beachten Sie jedoch, dass der Name bei der Verwendung von verkleinertem Code wahrscheinlich anders lautet.

44voto

SonOfALink Punkte 461

Meine Lösung war, sich nicht auf den Klassennamen zu verlassen. object.constructor.name funktioniert in der Theorie. Aber wenn man TypeScript in etwas wie Ionic verwendet, wird es in Flammen aufgehen, sobald man in die Produktion geht, weil der Produktionsmodus von Ionic den Javascript-Code minimiert. Also bekommen die Klassen Namen wie "a" und "e".

Was ich am Ende tat, war mit einer typeName-Klasse in allen meinen Objekten, die der Konstruktor den Klassennamen zuweist. So:

export class Person {
id: number;
name: string;
typeName: string;

constructor() {
typeName = "Person";
}

Ja, das war nicht die eigentliche Frage. Aber die Verwendung der constructor.name auf etwas, das möglicherweise erhalten minified auf der Straße ist nur betteln für Kopfschmerzen.

31voto

Ich weiß, dass ich zu spät dran bin, aber ich finde, dass das auch funktioniert.

var constructorString: string = this.constructor.toString();
var className: string = constructorString.match(/\w+/g)[1]; 

Alternativ...

var className: string = this.constructor.toString().match(/\w+/g)[1];

Der obige Code erhält den gesamten Konstruktorcode als Zeichenkette und wendet eine Regex an, um alle "Wörter" zu erhalten. Das erste Wort sollte "Funktion" und das zweite Wort der Name der Klasse sein.

Ich hoffe, das hilft.

27voto

Westy92 Punkte 14901

Sie müssen die Instanz zunächst auf any denn Function hat die Typdefinition keine name Eigentum.

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"

Aktualisierung:

Mit TypeScript 2.4 (und möglicherweise früher) kann der Code noch sauberer sein:

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"

20voto

ttugates Punkte 4998

Lösung mit Dekorateure die die Minifizierung/Auglifizierung überstehen

Wir verwenden die Codegenerierung, um unsere Entity-Klassen mit Metadaten auszustatten, wie folgt:

@name('Customer')
export class Customer {
  public custId: string;
  public name: string;
}

Dann verbrauchen Sie mit dem folgenden Hilfsmittel:

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);
}

Zusätzliche Informationen:

  • Sie müssen möglicherweise Folgendes installieren reflect-metadata
  • reflect-metadata ist Pollyfill, das von Mitgliedern von TypeScript für die vorgeschlagene ES7 Reflection API geschrieben wurde
  • Der Vorschlag für Dekoratoren in JS kann sein hier nachverfolgt

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X