5-1. 인터페이스

/** Interface */

interface Person {
  name: string;
  age: number;
  sayHi: () => void;
  sayBye(): void;
  sayBye(a: number): void;
}

type Person2 = {
  name: string;
  age: number;
  sayHi: () => void;
  sayBye(): void;
  sayBye(a: number): void;
} | number; // Union type possible

type UnionType = Person | number

const person: Person = {
  name: "kihoon",
  age: 25,
  sayHi: () => {
    console.log('hello');
  },
  sayBye: function (a?: number) {
    console.log('bye', a);
  }
};

const person2: Person | number = 1;

5-2. 인터페이스 확장하기 (extends - type alias에는 없는 기능)

/** Extending Interface */

interface Animal {
  name: string;
  family: string;
  age: number;
}

// type Animal = { // same
//   name: string;
//   family: string;
//   age: number;
// } 

interface Dog extends Animal {
  family: "Canidae";
  // family: 1 // error
  barks: boolean;
}

interface Cat extends Animal {
  family: "Felidae";
  claws: boolean;
}

/** extending multiple classes */

// interface DogCat extends Dog, Cat {} // error

interface Wolf extends Dog {
  howls: boolean;
}

interface WolfDog extends Dog, Wolf {}

const wolfDog: WolfDog = {
  name: 'Pluto',
  family: "Canidae",
  age: 8,
  barks: true,
  howls: true,
}

5-3. 인터페이스 합치기 Declaration Merging

Documentation - Declaration Merging

/** Declarization Merging */

interface Person {
  name: string;
}

interface Person {
  // name: number; // error - conflict
  // name: "kihoon"; // error - also conflict. extends와 다르게subtype이어도 안된다.
  // name: string; // 이렇게 같아야지만 가능. 하지만 굳이 이렇게 쓸 일이 있을까?
  age: number;
}

const person: Person = {
  name: "kihoon",
  age: 25,
};