Pobieranie nazwy klasy obiektu w czasie wykonywania

Czy możliwe jest uzyskanie nazwy klasy/typu obiektu w czasie wykonywania przy użyciu języka TypeScript?

class MyClass{}

var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"
 321
Author: Alexander Abakumov, 2012-11-28

10 answers

Prosta odpowiedź:

class MyClass {}

const instance = new MyClass();

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

Jednakże: uważaj, że nazwa będzie prawdopodobnie Inna podczas korzystania z minified code.

 528
Author: Mikael Couzic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-07 15:54:45

Wiem, że jestem spóźniona na imprezę, ale to też działa.

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

Alternatywnie...

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

Powyższy kod pobiera cały kod konstruktora jako ciąg znaków i stosuje regex, aby uzyskać wszystkie 'słowa'. Pierwszym słowem powinno być 'function', a drugim powinna być nazwa klasy.

Mam nadzieję, że to pomoże.
 29
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-09 06:49:40

Moim rozwiązaniem było nie polegać na nazwie klasy. object.constructor.name działa w teorii. Ale jeśli używasz maszynopisu w czymś takim jak Ionic, jak tylko przejdziesz do produkcji, to stanie w płomieniach, ponieważ tryb produkcyjny Ionic minimalizuje kod Javascript. Tak więc klasy otrzymują nazwy takie jak " a " i " e "

Skończyło się na tym, że miałem klasę typeName we wszystkich moich obiektach, którym konstruktor przypisuje nazwę klasy. Więc:

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

constructor() {
typeName = "Person";
}

Yes that wasn ' t what został poproszony, naprawdę. Ale za pomocą constructor.name na coś, co może potencjalnie dostać minified w dół drogi jest po prostu błaganie o ból głowy.

 27
Author: SonOfALink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-24 21:12:36

Zobacz to Pytanie .

Ponieważ TypeScript jest skompilowany do JavaScript, w czasie wykonywania jest uruchomiony JavaScript, więc te same zasady będą miały zastosowanie.

 20
Author: Matt Burland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59

Najpierw musisz oddać instancję do any, ponieważ definicja typu Function nie ma właściwości 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"

Aktualizacja:

Z maszynopisem 2.4 (i potencjalnie wcześniejszym) kod może być jeszcze czystszy:

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"
 15
Author: Westy92,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-14 16:30:31

W Angular2 może to pomóc w uzyskaniu nazwy komponentów:

    getName() {
        let comp:any = this.constructor;
        return comp.name;
    }

Comp: Dowolna jest potrzebna, ponieważ kompilator TypeScript wyda błędy, ponieważ funkcja początkowo nie ma nazwy właściwości.

 4
Author: Admir Sabanovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-06 19:17:39

Rozwiązanie za pomocą dekoratorów , które przetrwają minifikację / uglifikację

Używamy generowania kodu, aby ozdobić nasze klasy encji metadanymi w następujący sposób:

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

Następnie skonsumuj z następującym pomocnikiem:

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

Dodatkowe informacje:

  • Może być konieczne zainstalowanie reflect-metadata
  • W przeciwieństwie do innych języków, które nie są używane przez inne języki, nie są używane przez inne języki.]}
  • propozycja dla dekoratorów w JS może być śledzona tutaj
 4
Author: ttugates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-22 23:45:59

Pełny kod maszynopisu

public getClassName() {
    var funcNameRegex = /function (.{1,})\(/;
    var results  = (funcNameRegex).exec(this["constructor"].toString());
    return (results && results.length > 1) ? results[1] : "";
}
 3
Author: Nati Krisi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 15:00:56
  • musiałem dodać ".prototyp." do użycia: myClass.prototype.constructor.name.
  • W Przeciwnym Razie z następującym kodem : myClass.constructor.name, miałem błąd maszynopisu:

error TS2339: Property 'name' does not exist on type 'Function'.

 3
Author: Flox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-10 12:08:10

Jeśli już wiesz, jakich typów można się spodziewać (na przykład, gdy metoda zwraca typ union), możesz użyć strażników typu.

Na przykład dla typów prymitywnych można użyć typeof :

if (typeof thing === "number") {
  // Do stuff
}

Dla typów złożonych można użyć instanceof :

if (thing instanceof Array) {
  // Do stuff
}
 -3
Author: Cocowalla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-14 18:49:58