[英]Typescript generic type T toString
我认为不可能,但值得一问。 在泛型方法或类中,我想记录已使用的泛型 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 中转译并且不会产生预期的效果。 我尝试了各种事情,但没有成功。
有没有办法实际做到这一点?
编辑:为什么这不是重复的: 这个问题
问题和示例代码显示了如何取回对象而不是指定类型的名称。 此外,该方法不是通用的,因为如果您尝试传入具有构造函数参数的类型,它将显示错误:“ [ts] 类型为 'typeof MyType' 的参数不可分配给类型为 'new () => MyType 的参数'. " 此外,如果您在泛型方法中使用该函数,则不能将 T 用作参数,这意味着在需要从泛型 Type 中获取名称的任何地方,我都需要将 ctor 添加到参数中。
使用这里的答案,我对其进行了修改以更好地满足我的需求,但是,这仍然不是我的完整答案,因为即使面团可以工作,编译并且测试通过,以下代码显示了 VS 和 VS Code 中的错误。
辅助类:
export class TypeHelper {
static typeName(ctor: { name:string }) : string {
return ctor.name;
}
}
测试类(茉莉花规范):
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] 'T' 仅指一种类型,但在此处用作值。
我不是 TS 专家,但我会继续研究这个问题以尝试了解如何解决这个问题。
编辑:添加操场示例
好吧,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 类型名称。 这就是为什么这有效。
在搜索了所有互联网,制作了我自己的装饰器并摆弄了很多 Typescript 之后,我被这篇文章绊倒了:
基本上,只要Message
是一个类,您就可以使用Message.name
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.