是否可以在运行时使用TypeScript获取对象的类/类型名称?
class MyClass{}
var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"
是否可以在运行时使用TypeScript获取对象的类/类型名称?
class MyClass{}
var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"
Answers:
class MyClass {}
const instance = new MyClass();
console.log(instance.constructor.name); // MyClass
console.log(MyClass.name); // MyClass
但是:请注意,使用缩小代码时,名称可能会有所不同。
let instance: any = this.constructor; console.log(instance.name);
any是console.log(instance.constructor['name']);
interface Function { name: string; }-这将扩展“本地”定义。
MyClass.name如果要缩小代码,效果将不佳。因为它将缩小类的名称。
我知道我参加晚会很晚,但是我发现这也行得通。
var constructorString: string = this.constructor.toString();
var className: string = constructorString.match(/\w+/g)[1];
或者...
var className: string = this.constructor.toString().match(/\w+/g)[1];
上面的代码将整个构造函数代码作为字符串获取,并应用正则表达式以获取所有“单词”。第一个单词应该是“功能”,第二个单词应该是类的名称。
希望这可以帮助。
我的解决方案是不依赖类名。object.constructor.name在理论上起作用。但是,如果您在Ionic之类的产品中使用TypeScript,那么一旦投入生产,它就会大打折扣,因为Ionic的生产模式会缩减Javascript代码。因此,这些类得到了诸如“ a”和“ e”之类的命名名称。
我最终要做的是,在我的所有对象中都有一个typeName类,构造函数将其分配给该类名。所以:
export class Person {
id: number;
name: string;
typeName: string;
constructor() {
typeName = "Person";
}
是的,这不是真正的要求。但是,在可能会逐渐缩小的东西上使用constructor.name只是让人头疼。
您首先需要将实例转换为,any因为Function的类型定义没有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"
使用TypeScript 2.4(以及可能更早的版本),代码可以变得更加简洁:
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"
Property 'name' does not exist on type 'Function'.
(this as {}).constructor.name还是(this as object).constructor.name比any这要好,因为您实际上可以自动完成:-)
在Angular2中,这可以帮助获取组件名称:
getName() {
let comp:any = this.constructor;
return comp.name;
}
comp:any是必需的,因为Type函数最初没有属性名称,因此TypeScript编译将发出错误。
element.nativeElement-在指令上,您可以像这样获取组件的名称@Optional() element: ElementRef<HTMLElement>,然后使用 if (element != null && element.nativeElement.tagName.startsWith('APP-')) { this.name = element.nativeElement.tagName; }
完整的TypeScript代码
public getClassName() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(this["constructor"].toString());
return (results && results.length > 1) ? results[1] : "";
}
该解决方案在最小化丑陋之后起作用,但是需要用元数据修饰类。
我们使用代码生成来像这样用元数据修饰Entity类:
@name('Customer')
export class Customer {
public custId: string;
public name: string;
}
然后使用以下帮助程序进行消耗:
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);
}
如果您已经知道需要什么类型(例如,当方法返回联合类型时),则可以使用类型保护。
例如,对于原始类型,您可以使用typeof Guard:
if (typeof thing === "number") {
// Do stuff
}
对于复杂类型,可以使用instanceof guard:
if (thing instanceof Array) {
// Do stuff
}