TypeScript泛型接口<T>扩展相同名称

9

这在C#中显然可以正常工作,但在typescript中却不行,有没有办法解决,或者我只能使用不同的名称了?

export interface IThing<T> extends IThing {
 Value: T;
}

export interface IThing {
Name?: string;
ValueStr?: string;
Type?: string;
}

我收到了“IThing的所有声明必须具有相同的类型参数”的错误信息。

如果我说得不够清楚,请多包涵!


@maccettura 公平的观点 - Michael Harper
2个回答

11

您需要使用不同的名称,因为在识别接口时只有名称才起作用,而不是泛型类型参数的数量。

在Typescript中,泛型在编译时被擦除,因此无法区分泛型类的不同实例。虽然接口仅是编译时构造,可能也可以通过名称和泛型参数的数量来区分,但我猜想由于类的工作方式是这样决定使接口也以相同的方式工作。

一个解决方法是为接口使用默认类型参数:

export interface IThing<T = any> {
    Name?: string;
    ValueStr?: string;
    Type?: string; 
    Value: T;
}

var d: IThing;
var foo: IThing<number> 

实际上,你可以使用声明合并来实现这一点,但名称和类型参数必须匹配。 - Tao
2
@Tao,如果它们被合并了,那么它们就不是不同的接口了 :) 问题是你是否可以同时拥有一个带有通用参数和一个没有的接口,以区分像C#中一样的接口。 - Titian Cernicova-Dragomir
1
啊,好的,我没看懂问题的起源,因为我不太了解C#。:) 此外,当我发表我的答案时,extends是不存在的,所以它看起来像他试图将它们合并。 - Tao
这不对。在编译期间,_所有_类型都被擦除,而不仅仅是泛型。认为其他情况会带来痛苦。 - Aluan Haddad
@AluanHaddad 是的,所有类型注释都被擦除了,但你可以根据它们的构造函数区分两个类,并且使用 instanceof 可以区分两个类。但是,没有任何东西可以区分同一泛型类的两个不同实例。 - Titian Cernicova-Dragomir
@TitianCernicova-Dragomir 哦,我明白你为什么这样表达了。然而,类之间的区别不是类型系统的区别。instanceof 不是一种类型测试。 - Aluan Haddad

0

编辑2

我误解了这个问题,所以这不是正确的答案。我会把它留在这里以展示如何使用声明合并。


第一个声明有类型参数T,而第二个没有。只需确保它们都具有类型参数即可。

export interface IThing<T> {
    Name?: string;
    ValueStr?: string;
    Type?: string;
}

编辑

interface IThing<T> extends IThing

这样做行不通,就像我上面说的一样,确保两个接口声明具有相同的名称和相同的类型参数

interface IThing<T>

游乐场演示


1
声明合并实际上是不允许的原因之一。使用默认类型参数时,你是否想要扩展或合并将会产生歧义。 - Aluan Haddad

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