打字稿泛型类型 T toString
Posted
技术标签:
【中文标题】打字稿泛型类型 T toString【英文标题】:Typescript generic type T toString 【发布时间】:2018-04-27 16:57:28 【问题描述】:我认为不可能,但值得一问。 在泛型方法或类中,我想记录已使用的泛型 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
问题和示例代码显示了如何取回对象而不是指定类型的名称。 该方法也不是通用的,因为如果您尝试传入具有构造函数参数的类型,它将显示错误: “[ts] 'typeof MyType' 类型的参数不能分配给 'new () => MyType' 类型的参数。” 此外,如果您在泛型方法中使用该函数,则不能使用 T 作为参数,这意味着我需要从泛型类型中获取名称的任何地方,都需要将 ctor 添加到参数中。
【问题讨论】:
相关:***.com/questions/41160690/… Is it possible to get the type name of a generic type?的可能重复 【参考方案1】:在搜索了所有的互联网、制作自己的装饰器并大量摆弄 Typescript 之后,我被这篇文章绊倒了:
Get an object's class name at runtime
基本上,只要Message
是一个类,您就可以使用Message.name
。
但是要小心,因为如果在进行生产构建时类名被缩小,这可能会停止工作,所以在使用这种方法之前请检查。
【讨论】:
【参考方案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 类型名称。这就是它起作用的原因。
【讨论】:
安德烈亚斯,鉴于你所说,有没有这样的解决方案来做我需要的?还是不可能? @Manuel:您在最初的问题中要求的内容是不可能的。有关详细信息,请参阅我编辑的答案【参考方案3】:使用答案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] 'T' 仅指一种类型,但在这里用作值。
我不是 TS 专家,但我会继续研究以尝试了解如何解决此问题。
编辑:添加playground example
【讨论】:
以上是关于打字稿泛型类型 T toString的主要内容,如果未能解决你的问题,请参考以下文章