Interface



インタフェースはタイプチェックに使用され、変数/関数/クラスに使用できます.
ES 6はインタフェースをサポートしないが、TypeScriptはインタフェースをサポートする.

✨ Interface


インタフェースは상호 간에 정의한 약속 혹은 규칙を表します.
インタフェースはクラスと類似しているが,인스턴스を直接生成することはできず,すべての方法が抽象的な方法である.

へんすう


インタフェースは変数タイプとして使用でき、インタフェースの変数がインタフェースのフォーマットを守らなければならないことを宣言します.
👇 サンプルコードを見てみましょう.
// 인터페이스 Song을 정의
interface Song {
  artist : string;
  title : string;
  isDance : boolean;
}
// 변수 song의 타입으로 Song 인터페이스를 선언
let song : Song;

// 변수 song은 Song 인터페이스를 지켜야 한다.
song = { artist : "IVE", title : "LOVE DIVE", isDance : true };
👇 上記の例では、関数インタフェースを使用して関数パラメータタイプのコードを宣言します.
let songs : Song[] = [
  { artist : "IVE", title : "LOVE DIVE", isDance : true }];

function addSong(song: Song){
  songs = [ ...songs, song];
}

const newSong : Song = { artist : "RedVelet", title : "Feel My Rhythm", isDance : true };
addSong(newSong);

console.log(songs);
// [
//  { artist: 'IVE', title: 'LOVE DIVE', isDance: true },
//  { artist: 'RedVelet', title: 'Feel My Rhythm', isDance: true }
//]
このようにインタフェースを使用すると、オブジェクトを関数に渡すときに複雑なパラメータチェックを必要としないため、非常に便利です.

n.関数


関数のパラメータとしてだけでなく、関数のタイプとしてインタフェースを使用することもできます.
関数のインタフェースには、宣言タイプのパラメータリストと戻りタイプを定義する必要があります.
// 연습실 크기 함수 인터페이스의 정의
interface PracticeRoomFun {
  (roomWidth: number, roomHeight: number): number;
}

const practiceRoom: PracticeRoomFun = function (width: number, height: number) {
  return width * width * height;
};

console.log(practiceRoom(8, 20)); // 1280

カテゴリ


クラスの後にimplementsが作成され、인터페이스が宣言された場合、クラスは指定されたインタフェースに従う必要があります.
// 노래 인터페이스 정의
interface ISong {
  artist: string;
  title: string;
  isDance: boolean;
}

// Song 클래스는 ISong 인터페이스를 구현하여야 한다.
class Song implements ISong {
  constructor(
    public artist: string,
    public title: string,
    public isDance: boolean
  ) {}
}
// 클래스는 직접 인스턴스 생성 가능
const song = new Song("IVE", "LOVE DIVE", true);

console.log(song);
// Song { artist: 'IVE', title: 'LOVE DIVE', isDance: true }
インタフェースをクラスに適用すると、一貫性を維持できます.

¥インタフェースvsクラス¥

  • 공통점propertyとメソッド
  • 차이점インスタンスを直接作成することはできません.
  • また、インタフェースにはメソッドが含まれていてもよいし、メソッドが含まれていてもよい.
    しかし、すべての方法は抽象的な方法でなければならない.
    // 인터페이스의 정의
    interface ISong {
      artist: string;
      title: string;
      isDance: boolean;
      sayDance(): void;
    }
    
    class SongMethod implements ISong {
      // 인터페이스에서 정의한 프로퍼티의 구현
      constructor(
        public artist: string,
        public title: string,
        public isDance: boolean
      ) {}
    
      // 인터페이스에서 정의한 추상 메소드의 구현
      sayDance() {
        console.log(`오늘은 ${this.artist}${this.title}을 출거야 💃`);
      }
    }
    
    function danceInfo(song: ISong): void {
      song.sayDance();
    }
    
    const todaySong = new SongMethod("IVE", "LOVE DIVE", true);
    danceInfo(todaySong);
    // 오늘은 IVE의 LOVE DIVE을 출거야 💃

    Duck typing


    TypeScriptがインタフェースで定義されたPropertyまたはメソッドを持っている場合、他のPropertyが存在するかどうかにかかわらず、誤って通過することなくインタフェースが実現されたと認定されます.
    すなわち,インタフェースが実装されても,すべてのタイプのチェックを通過することはできない.
    👇 サンプルコードを見てみましょう.
    interface IDance {
      artist: string;
      title: string;
    }
    
    function 춤추자(dance: IDance): void {
      console.log(`오늘 춤출 곡은 ${dance.artist}${dance.title}입니댜 💃 `);
    }
    
    const dance = { artist: "IVE", title: "LOVE DIVE" , isDance : false};
    춤추자(dance); 
    //오늘 춤출 곡은 IVE의 LOVE DIVE입니댜 💃 
    変数danceはインタフェースIDanceと一致しません.
    しかし、アーティストやtitleの専門性を持っているという理由で、インタフェースとされている.
    👇 インタフェースはJavaScriptの標準ではないので、タイプスクリプトをJavaScriptに変更すると、次のようにインタフェースが削除されます.
    function 춤추자(dance) {
        console.log("\uC624\uB298 \uCDA4\uCD9C \uACE1\uC740 ".concat(dance.artist, "\uC758 ").concat(dance.title, "\uC785\uB2C8\uB31C \uD83D\uDC83 "));
    }
    var dance = { artist: "IVE", title: "LOVE DIVE", isDance: false };
    춤추자(dance); //오늘 춤출 곡은 IVE의 LOVE DIVE입니댜 💃
    道徳的なタイプは等級にも適用されます.
    interface ICheer {
      cheer(): void;
    }
    // 인터페이스 ICheer 구현
    class SeoheeCheer implements ICheer {
      cheer() {
        console.log("서히 체고");
      }
    }
    // 인터페이스 ICheer 구현하지 않음
    class ClappingCheer {
      cheer() {
        console.log("Clap, clap, clap, clap, clap clap clap!");
      }
    }
    
    function makeCheer(cheer: ICheer): void {
      cheer.cheer();
    }
    // 에러 없이 처리
    makeCheer(new SeoheeCheer());       // 서히 체고
    makeCheer(new ClappingCheer());     // Clap, clap, clap, clap, clap clap clap!
    SeoheeCheerはICheerを実現したが,ClippingCheerはICheerを実現しなかった.
    しかし,makeCheer関数で2つのクラスのインスタンスをそれぞれ渡しても,それらがエラー処理されていないと判断できる.

    オプションの追加


    インタフェースを使用する場合は、インタフェースで定義されているすべてのプロパティを使用する必要はありません.
    属性の後に?を付けると、オプション機能が有効になります.
    interface 인터페이스_이름 {
      속성? : 타입;
    }
    👇 前のサンプルコードにオプション機能を追加します.
    interface IDance {
      artist: string;
      title?: string;
    }
    
    function 춤추자(dance: IDance): void {
      console.log(`오늘 춤출 곡은 ${dance.artist}${dance.title}입니댜 💃 `);
    }
    
    let dancer = { artist: "IVE" };
    춤추자(dancer);
    //오늘 춤출 곡은 IVE의 undefined입니댜 💃 
    オプションに指定された属性に値が割り当てられていない場合は、定義されていない割り当てが表示されます.

    🤔 では、なぜタイプが重要だと思うタイプスクリプトでオプション属性を使用するのでしょうか。


    長所


    これは、属性を選択的に使用するだけでなく、ユーザーインタフェースで定義されていない属性を伝えることができるからです.
    function 춤추자(dance: IDance): void {
      console.log(`오늘 춤출 곡은 ${dance.artist}${dance.songTitle}입니댜 💃 `);
      // 'IDance' 형식에 'songTitle' 속성이 없습니다.ts(2339
    }
    上記のコードのように存在しないプロパティでは、タイプスクリプトにエラーが表示されます.

    すべて読み取り専用


    インタフェースを使用してオブジェクトを作成したときにのみ値が割り当てられ、その後は変更できません.readonlyキーワードは、属性の前に使用されます.
    interface 인터페이스_이름 {
      readonlyt 속성 : 타입;
    }
    👇 読み取り専用プロパティを追加します.
    interface IDance {
      readonly artist: string;
      title?: string;
    }
    
    // 인터페이스 객체 생성
    let dance: IDance = { artist: "IVE" };
    
    // 읽기 전용 속성
    dance.artist = "Red Velvet";	//읽기 전용 속성이므로 'artist'에 할당할 수 없습니다.ts(2540)
    読み取り専用プロパティを再割り当てしようとすると、エラーが発生します.

    整列


    読み取り専用プロパティを配列形式で作成する場合は、ReadonlyArray< T >タイプを使用します.
    👇 一度に割り当てられた配列の内容は変更できないので、注意して使用してください.
    let favoriteSong: ReadonlyArray<string> = ["icy", "살짝 설렜어", "LOVE DIVE"];
    
    favoriteSong.push("Real Love");
    // 'readonly string[]' 형식에 'push' 속성이 없습니다.ts(2339)
    favoriteSong[0] = "Feel My Rhythm";
    // 'readonly string[]' 형식의 인덱스 시그니처는 읽기만 허용됩니다.ts(2542)

    世代インタフェースの継承


    継承クラスが使用するように、インタフェースはextendsというキーワードを使用して継承を実現することもできる.
    interface SongInfo{
        artist: string;
        title: string;
    }
    interface DancerInfo extends SongInfo{
        name: string;
        age: number;
    }
    interface Group extends DancerInfo{
        people: number;
    }
    
    let soptKpop = {} as Group;
    soptKpop.people = 20;
    // Group
    soptKpop.age = 24;
    // Group extends DancerInfo 
    soptKpop.artist = "IVE";			
    soptKpop.title = "LOVE DIVE";
    // Group extends DancerInfo extends SongInfo

    組合せタイプ


    JAvascriptの拡張タイプスクリプトも同様に動的特性を有するため、複数のタイプを組み合わせてインタフェースを実現することができる.
    👇 関数タイプオブジェクトタイプのインタフェースコードも定義します.
    interface IGroup {
      (todayLearned: string): string;
      perfomanceTime: number;
      perfomanceLocation(location: string): void;
    }
    function myGroup(): IGroup {
      let group = function (todayLearned: string) {
        return todayLearned;
      } as IGroup;
      group.perfomanceTime = 20000;
      group.perfomanceLocation = function (this) {
        console.log(this.perfomanceTime + "시간 공연예정");
      };
      return group;
    }
    let soptKPop = myGroup();
    console.log(soptKPop("LOVE DIVE"));
    // LOVE DIVE
    soptKPop.perfomanceTime = 30000;
    soptKPop.perfomanceLocation("홍대");
    // 30000시간 공연예정

    🌈 n/a.結論


    Type ScriptでObejctタイプを宣言するときにインタフェースとtypeを使用します.デフォルトでは、使用可能なすべてのインタフェースが表すタイプをインタフェースで表す必要があります.基本タイプに新しい名前または汎用タイプを命名する場合は、インタフェース能力以外の部分でのみタイプ別名を使用できます.
    📚 学習の参考資料📚
  • タイプスクリプトマニュアル-インタフェース
  • 12.5 TypeScript - Interface インタフェース
  • ✨ item4. 構造化タイプを熟知している