是否有可能在运行时使用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"
当前回答
使用装饰器的解决方案,在缩小/丑陋化中幸存
我们使用代码生成用元数据来装饰我们的实体类,如下所示:
@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);
}
额外信息:
您可能需要安装reflect-metadata reflect-metadata是由TypeScript成员为提议的ES7 Reflection API编写的填充 JS中关于装饰器的建议可以在这里找到
其他回答
简单的回答:
class MyClass {}
const instance = new MyClass();
console.log(instance.constructor.name); // MyClass
console.log(MyClass.name); // MyClass
但是,要注意,在使用简化代码时,名称可能会有所不同。
如果您已经知道预期的类型(例如,当一个方法返回联合类型时),那么您可以使用类型保护。
例如,对于基本类型,你可以使用typeof守卫:
if (typeof thing === "number") {
// Do stuff
}
对于复杂类型,你可以使用一个instanceof guard:
if (thing instanceof Array) {
// Do stuff
}
使用装饰器的解决方案,在缩小/丑陋化中幸存
我们使用代码生成用元数据来装饰我们的实体类,如下所示:
@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);
}
额外信息:
您可能需要安装reflect-metadata reflect-metadata是由TypeScript成员为提议的ES7 Reflection API编写的填充 JS中关于装饰器的建议可以在这里找到
我的解决方案是不依赖类名。Object.constructor.name在理论上是可行的。但如果你在Ionic这样的平台上使用TypeScript,一旦你进入生产模式,它就会陷入困境,因为Ionic的生产模式减少了Javascript代码。所以类被命名为“a”和“e”。
我最后做的是在我的所有对象中都有一个typeName类,构造函数将类名赋给它。所以:
export class Person {
id: number;
name: string;
typeName: string;
constructor() {
typeName = "Person";
}
是的,这不是问的,真的。但是将constructor.name用于将来可能会被最小化的东西上是在自找麻烦。
看这个问题。
因为TypeScript被编译成JavaScript,所以在运行时你运行的是JavaScript,所以同样的规则也适用。