web-dev-qa-db-fra.com

Obtenir le nom de la classe d'un objet lors de l'exécution dans TypeScript

Est-il possible d'obtenir le nom de classe/type d'un objet au moment de l'exécution à l'aide de typescript?

class MyClass{}

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

Réponse simple:

class MyClass {}

const instance = new MyClass();

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

Cependant, prenez garde que le nom sera probablement différent si vous utilisez un code minifié.

333
Mikael Couzic

Je sais que je suis en retard à la fête, mais je trouve que ça marche aussi.

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

Alternativement ...

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

Le code ci-dessus obtient le code de constructeur entier en tant que chaîne et applique une expression rationnelle pour obtenir tous les "mots". Le premier mot doit être 'fonction' et le deuxième mot doit être le nom de la classe.

J'espère que cela t'aides.

23
user2278642

Voir cette question

Étant donné que TypeScript est compilé en JavaScript, vous exécutez JavaScript au moment de l'exécution, de sorte que les mêmes règles s'appliquent.

20
Matt Burland

Ma solution était de ne pas compter sur le nom de la classe. object.constructor.name fonctionne en théorie. Mais si vous utilisez TypeScript dans quelque chose comme Ionic, dès que vous allez en production, cela va flamber car le mode de production d'Ionic minimise le code Javascript. Ainsi, les classes reçoivent des objets nommés comme "a" et "e". 

J'ai fini par avoir une classe typeName dans tous mes objets, à laquelle le constructeur attribue le nom de la classe. Alors:

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

constructor() {
typeName = "Person";
}

Oui, ce n’était pas ce qui était demandé, vraiment. Mais utiliser le constructeur.name sur quelque chose qui pourrait éventuellement être minié sur la route est juste mendier pour un mal de tête.

15
SonOfALink

Vous devez d'abord convertir l'instance en any car la définition de type de Function n'a pas de propriété 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"

Mettre à jour:

Avec TypeScript 2.4 (et potentiellement antérieurement), le code peut être encore plus propre:

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"
9
Westy92

Dans Angular2, cela peut aider à obtenir le nom des composants:

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

comp: any est nécessaire car la compilation TypeScript générera des erreurs, puisque Function ne possède pas initialement le nom de la propriété.

5
Admir Sabanovic
  • Doit ajouter ".prototype." pour utiliser: myClass.prototype.constructor.name.
  • Sinon, avec le code suivant: myClass.constructor.name, j'avais l'erreur TypeScript: 

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

3
Flox

Le code complet TypeScript 

public getClassName() {
    var funcNameRegex = /function (.{1,})\(/;
    var results  = (funcNameRegex).exec(this["constructor"].toString());
    return (results && results.length > 1) ? results[1] : "";
}
3
Nati Krisi

Il suffit de faire

class TestClass {
  getClassName() {
    return this.constructor.name;
  }
   callMe(){
    console.log(this.getClassName());
   }
}
0
Remario

Si vous savez déjà à quels types s'attendre (par exemple, lorsqu'une méthode retourne un union type ), vous pouvez utiliser des gardes de type.

Par exemple, pour les types primitifs, vous pouvez utiliser un typeof guard :

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

Pour les types complexes, vous pouvez utiliser un instanceof guard :

if (thing instanceof Array) {
  // Do stuff
}
0
Cocowalla