您可以为TypeScript泛型指定多个类型约束吗


83

我有一个像下面的示例这样的通用接口,具有一个单一类型约束:

export interface IExample<T extends MyClass> {
    getById(id: number): T;
}

是否可以指定多个类型约束而不是仅指定一个?

Answers:


87

Typescript不提供获取泛型类型的多重继承的语法。但是,可以通过使用Union类型和Intersection类型来实现相似的语义。在您的情况下,您需要一个交叉点:

interface Example<T extends MyClass & OtherClass> {}

对于两种类型的联合:

interface Example<T extends MyClass | OtherClass> {}

4
联合类型是实现此目标的一种好方法,因为您无需为约束的唯一目的创建接口。他们早在2013年就不存在-但这绝对是我建议现在使用的方式。
芬顿

5
这个答案是错误的。联合类型的语义与扩展两个不同类型的语义完全不同。
AlexG '16

3
@AlexG确保这与扩展两种类型不同,但与实现两个接口相同。
STO

6
还请记住,Typescript也支持交集类型。因此<T extends MyInterfaceA & MyInterfaceB>要求类型实现两个接口。
泰勒·克劳捷

2
据我了解,语义extends A|B是扩展A或B以及extends A & B扩展两者!所以也许您应该在答案中同时指定两者
。...– Pipo

34

解决此问题的方法是使用超级接口(它还会回答“为什么要允许接口从类继承”的问题)。

interface ISuperInterface extends MyClass, OtherClass {

}

export interface IExample<T extends ISuperInterface> {
    getById(id: number): T;
}

12
这是正确的解决方案。从两个类扩展接口有点吓人,但是-如果两个都声明为私有成员,则该接口将无法实现
Ryan Cavanaugh 2013年

1

引用有关从类派生的接口的评论...名称是什么?

我在0.9.0规范的第3.5节中找到了这一点:

接口声明仅引入命名类型,而类声明引入命名类型和构造函数,这些函数创建这些命名类型的实现实例。由类和接口声明引入的命名类型只有细微的差别(类不能声明可选成员,接口不能声明私有成员),并且在大多数情况下都是可互换的。特别是,只有公共成员的类声明会引入命名类型,它们的功能与接口声明创建的类型完全相同。


现在实现了可选的类成员:github.com/Microsoft/TypeScript/pull/8625
Stefan Rein
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.