繁体   English   中英

打字稿泛型类型 T toString

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM