如何获取 TypeScript 中泛型类<T>的名称?

38

我的泛型类

 export class BaseService<T> {
 public subUrl;
 constructor(public repo:RepogitoryService) { }
}

我该如何将T的类名存储在本地变量中?

5个回答

28

你必须明白,TypeScript只是一个转译器(将代码编译成JavaScript)。其中一些语法糖(例如泛型)仅在类型检查阶段起作用(并且对于IDE/文本编辑器中的智能感知非常有帮助)。

然而,在运行时进行变量赋值,实际上就是普通的JavaScript。在运行时,没有类型和泛型。

但以下是我会采取的最简单方法:

class Some<T> {
    private TName : string;
    constructor(x : T&Function) {
        this.TName = x.name;
    }
}

class Another {

}

const some = new Some<Another>(Another);

为什么TName是私有的?如何访问some.TName?对我来说,答案不完整。 - hakan
16
OP询问如何将通用类型名称存储为本地变量,这正是这段代码所做的。该变量的可见性与原始问题无关。 - Crono
2
如果Another中有一些字段,这似乎无法正常工作。 - Marian Simonca

24

durisvk10提供的解决方法已经涉及到了这个主题,我想补充一点:我更倾向于使用
x: new () => T而不是x: T&Function

像这样:

...
constructor(x : new () => T) {
    this.TName = x.name;
}    
...

3
请解释一下这个。 - Mustafa Magdy
5
在方法体中不能使用泛型,正如durisvk10所解释的那样,它只在类型检查阶段起作用。但是您可以将类型作为参数传递给您的方法(特别是构造函数)。通过使用此类型表示法,您告诉类型检查器您在此处期望具有空构造函数的类型(new() => T)。您可以在这里阅读更多关于此主题的信息:这里这里 - Yaremenko Andrii
这很不错。 - avidenic

12
很抱歉,您不能这样做。TypeScript 是一种静态类型检查器,不支持像 Java 一样在运行时进行类型反射。这是因为 TypeScript 的源代码被转译成 JavaScript。
然而,未来可能会有这种支持的希望,因为 TypeScript 引入了一个名为“自定义转换器”的新功能。这些转换器是插件,可以钩入转译过程,从而为类型反射提供更丰富的功能。其中一个示例是 ts-transformer-keys

2
它不需要运行时类型检查。它有一个编译阶段,可以为类型插入一个字符串值... - Douglas Gaskell
事实上,我已经构建了该变压器。请参见我的答案: https://dev59.com/ClYN5IYBdhLWcg3whYe3#71244450 - William Lahti

4
将对象强制转换为Object并获取构造函数名称?
function nameOf(object: Object): string {
    return object.constructor.name;
}

3

Typescript会在生成的JavaScript中移除所有的类型信息(包括运行时期),但是由于Typescript提供的“转换器”特性,现在可以编写一个转换器来在运行时期暴露这些信息。我已经做到了这一点,可以参见https://typescript-rtti.org/ - 不需要装饰器,而且它比emitDecoratorMetadata更加全面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接