Typescript泛型类型T toString

时间:2017-11-14 16:41:23

标签: typescript types

我认为不可能,但值得一提。 在泛型方法或类中,我想记录已使用的泛型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添加到参数中。

3 个答案:

答案 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