TypeScriptジェネリックに複数の型制約を指定できますか


83

この例のように、単一の型制約を持つ汎用インターフェースがあります。

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

1つだけではなく複数の型制約を指定することは可能ですか?

回答:


87

Typescriptは、ジェネリック型の多重継承を取得するための構文を提供していません。ただし、UnionタイプとIntersectionタイプを使用することで、同様のセマンティクスを実現できます。あなたの場合、あなたは交差点が欲しいです:

interface Example<T extends MyClass & OtherClass> {}

両方のタイプのユニオンの場合:

interface Example<T extends MyClass | OtherClass> {}

4
制約の唯一の目的のためにインターフェースを作成する必要がないため、共用体タイプはこれを実現するための優れた方法です。それらは2013年には存在しませんでしたが、これは間違いなく今私が推奨する方法です。
フェントン2016

5
この答えは間違っています。共用体型には、2つの異なる型を拡張するのと同じセマンティクスはありません。
AlexG 2016

3
@AlexG確かに、これは2つのタイプを拡張することと同じではなく、2つのインターフェースを実装することと同じです。
STO 2016年

6
Typescriptは交差型もサポートしていることにも注意してください。したがって<T extends MyInterfaceA & MyInterfaceB>、タイプは両方のインターフェースを実装する必要があります。
Tyler Cloutier 2018

2
私が理解している限り、extends A|BisはAまたはBをextends A & B拡張し、両方を拡張します。ので、多分あなたは....あなたの答えの両方を指定する必要があります
ピポサル

34

この回避策は、スーパーインターフェイスを使用することです(これは、「インターフェイスがクラスから継承できるようにする理由」という質問にも答えます)。

interface ISuperInterface extends MyClass, OtherClass {

}

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

12
これが正しい解決策です。2つのクラスからインターフェイスを拡張するのはちょっと怖いですが、両方がプライベートメンバーを宣言している場合、インターフェイスは実現できません
Ryan Cavanaugh 2013年

1

クラスから派生したインターフェースについてのコメントを参照してください...名前には何が含まれていますか?

0.9.0仕様のセクション3.5でこれを見つけました:

インターフェイス宣言は名前付き型のみを導入しますが、クラス宣言は名前付き型とそれらの名前付き型の実装のインスタンスを作成するコンストラクター関数を導入します。クラス宣言とインターフェイス宣言によって導入された名前付きタイプには、わずかな違いしかなく(クラスはオプションのメンバーを宣言できず、インターフェイスはプライベートメンバーを宣言できません)、ほとんどのコンテキストで交換可能です。特に、パブリックメンバーのみを含むクラス宣言では、インターフェイス宣言によって作成されたものとまったく同じように機能する名前付き型が導入されます。


オプションのクラスメンバーが実装されました:github.com/Microsoft/TypeScript/pull/8625
Stefan Rein
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.