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
変数にカーソルを合わせると、string
を渡しても、const per: string
ではなくconst per: number
が表示されます。 ] 口論。
const per = person.speak("bacon");
これは、同じ名前の関数パラメーターにtype
として文字列リテラルがある場合のすべてのインターフェースexpectに当てはまります。 上記と同じ順序に従いますが、文字列リテラルタイプの関数の優先順位が高くなるため、一番上に表示されます。
注目に値するのは、後のインターフェイスの文字列リテラルは、上記で説明したように最初のインターフェイスの前に表示されることです。
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); }
それでおしまい。 これがお役に立てば幸いです。 😊😎