我认为不可能,但值得一提。 在泛型方法或类中,我想记录已使用的泛型T类型的名称,我需要它作为字符串。
想象一下像这样的方法:
static getTypeName<T>(): string {
return typeof T; // This is wrong
}
我希望能够以这种方式使用它:
let m = getTypeName<Message>(); // Expected string "Message"
let p = getTypeName<Person>(); // Expected string "Person"
以上 getTypeName 错误,甚至无法构建。 typeof将在JS中进行转换,并且不会产生预期的效果。 我尝试了各种各样的事情但没有成功。
有没有办法真正做到这一点?
编辑:为什么这不是重复:this question
问题和示例代码显示了如何获取对象而不是指定类型的名称。 此方法也不是通用的,因为如果您尝试传入具有构造函数参数的Type,它将显示错误: &#34; [ts] MyType&#39;类型&#39;类型的参数不能分配给&#39; new()=&gt;类型的参数的MyType&#39; &#34; 此外,如果您在泛型方法中使用该函数,则不能使用T作为参数,这意味着我需要从泛型类型中获取名称,我需要将ctor添加到参数中。
答案 0 :(得分:2)
好吧,TypeScript中的泛型只是有助于类型检查的结构。 “ T”实际上是“无”-没什么可以翻译成JavaScript的。但是您需要使用此构造函数来获取类型名称。这就是为什么您收到该错误消息的原因。您只提供了一个类型,但需要一个值(具有该构造函数的值)才能使代码正常工作。
编辑:
无论如何,您需要做的是提供一些JavaScript对象。这样的事情会起作用:
class Foo<T> {
test: T;
constructor(value: T) {
this.test = value;
}
getTypeNameOfTest(): string {
return this.test.constructor.name;
}
}
const foo = new Foo<Date>(new Date());
foo.getTypeNameOfTest(); // => "Date"
const baa = new Foo<string>("Howdy");
baa.getTypeNameOfTest(); // => "string"
但是在这里,您提供了一个真正的JavaScript对象,而不仅仅是TypeScript类型名称。这就是为什么这样。
答案 1 :(得分:0)
使用答案here,我对其进行了调整以更好地满足我的需求,但是,这仍然不是我的完整答案,因为即使面团工作,编译和测试通过,以下代码显示错误VS和VS代码。
助手类:
export class TypeHelper {
static typeName(ctor: { name:string }) : string {
return ctor.name;
}
}
测试类(Jasmine规范):
import { TypeHelper } from './../util/TypeHelper';
class MyClass {
public MyGenericMethod<T>(): string {
let iNeedTheTypeNameHere = TypeHelper.typeName(T);
return `Use the string here somehow: ${iNeedTheTypeNameHere}`;
}
}
describe("TypeHelper", () => {
describe("TypeHelper", () => {
it("typeName, returns the string type name of the Class passed as parameter", () => {
let t = TypeHelper.typeName(TypeHelper);
expect(t).toBe("TypeHelper");
let m = TypeHelper.typeName(MyClass);
expect(m).toBe("MyClass");
});
it("typeName, returns the string type name of a generic type T passed as parameter", () => {
let myClass = new MyClass();
let t = myClass.MyGenericMethod<TypeHelper>();
expect(t).toBe("TypeHelper");
let m = myClass.MyGenericMethod<MyClass>();
expect(m).toBe("MyClass");
});
});
});
错误: [ts]&#39; T&#39;仅指类型,但在此处用作值。
我不是TS专家,但我会继续研究,以了解如何解决这个问题。
编辑:已添加playground example
答案 2 :(得分:0)
搜索了所有互联网,制作了自己的装饰器并摆弄了Typescript A LOT之后,我跳了一下这篇文章:
Get an object's class name at runtime
基本上,只要Message.name
是一类,就可以使用Message
。