TypeScriptでのインターフェイス宣言のマージ
TypeScript Mixins に関する以前の投稿では、TypeScriptでの宣言のマージについて簡単に説明しました。 これらの一連の投稿では、インターフェース宣言のマージを伴うインターフェースから始めて、もう少し深く掘り下げていきます。
宣言のマージとは何ですか?
宣言のマージとは、TypeScriptコンパイラーが、同じ名前の場合に2つ以上のタイプを1つの宣言にマージすることです。
TypeScriptを使用すると、次のような複数のタイプをマージできます。 interface
と interface
, enum
と enum
, namespace
と namespace
、など。 許可されていない注目すべきマージの1つは class
と class
マージ。 そのような機能が必要な場合は、ミックスインをチェックアウトしてください。
始めましょう interface
と interface
例を見てマージします。
interface Person {
name: string;
}
interface Person {
age: number;
}
interface Person {
height: number;
}
class Employee implements Person {
name = "Mensah"
age = 100;
height = 40
}
const employee = new Employee();
console.log(employee) // {name: "Mensah", age: 100, height: 40}
すべてのインターフェイスが同じ名前で宣言されているため、 Person
、それらは1つの定義にマージされるため、 Employee
クラスには、すべてのインターフェイスのプロパティが含まれています。
インターフェイスの同じプロパティ名(非関数)
マージされるインターフェイスのいずれかに同じプロパティ名が含まれていて、そのプロパティが関数ではない場合、 type
プロパティの数は同じである必要があります。そうでない場合、コンパイラはエラーをスローします。
interface Person {
name: string;
zipCode: string;
}
interface Person {
age: number;
zipCode: string; // acceptable
}
interface Person {
zipCode: number; // error
}
インターフェイス(関数)の同じプロパティ名
マージされたインターフェイスの要素が関数であり、それらが同じ名前である場合、それらはオーバーロードされます。つまり、 type
渡された引数のうち、適切な関数が呼び出されます。
interface Person {
speak(words: string);
}
interface Person {
speak(words: number);
}
const person: Person = {
speak: (wordsOrNum) => wordsOrNum
}
console.log(person.speak("Hi")) // speak(words: string) is used
console.log(person.speak(2)) // speak(words: number) is used
同じシグニチャ関数を含むインターフェイスがマージされると、最後に宣言されたインターフェイスの関数がマージされたインターフェイスの上部に表示され、最初のインターフェイスで宣言された関数が下部に表示されます。
interface Person {
speak(words:string);
}
interface Person {
speak(words: any);
}
interface Person {
speak(words: number);
speak(words: boolean);
}
// This is how the final merged interface looks like
interface Person {
// functions in the last interface appear at the top
speak(words: number);
speak(words: boolean);
// function in the middle interface appears next
speak(words: any):number;
// function in the first interface appears last
speak(words: string):string;
}
これは、後で宣言されたインターフェイスの方が、最初に宣言されたインターフェイスよりも優先されるためです。 したがって、上記の例では、 speak(words: string)
最終的にマージされたため、呼び出されることはありません Person
インターフェース、 speak(words: any):number
前に来る speak(words: string):string
それ以来 any
あらゆるタイプを表すことができ、たとえ string
として渡されます argument
.
これを証明するために、 per
以下のコードの変数、それは表示されます const per: number
ではなく const per: string
私たちが通過しているにもかかわらず string
口論。
const per = person.speak("bacon");
これは、同じ名前の関数パラメーターに文字列リテラルが含まれている場合、すべてのインターフェイスexpectedに当てはまります。 type
. 上記と同じ順序に従いますが、文字列リテラルタイプの関数の優先順位が高くなるため、一番上に表示されます。
注目に値するのは、後のインターフェイスの文字列リテラルは、上記で説明したように最初のインターフェイスの前に表示されることです。
interface Person {
speak(words: number);
speak(words: "World!"); // string literal type
}
interface Person {
speak(words: "Hello"); // string literal type
}
interface Person {
speak(words: string);
}
// merged interface output.
interface Person {
// string literals are given precedence
speak(words: "Hello");
speak(words: "World!");
// the rest of the functions are arranged using the same rules.
speak(words: string);
speak(words: number);
}
それでおしまい。 これがお役に立てば幸いです。 😊😎