type A = { age: 1 };
interface A {
  age: 1;
}
type A = string;
interface A string; // 이런 문법은 없다. {} 빠짐
type A = (x: number) = number;
interface A {
  // 키명: 키값
  (x: number): number;
}
// type 과 interface 의 차이 4

// type 에서만 사용 가능
type String = string;
type unionT = string | number;
type tupleT = [string, number];

// interface 에서만 사용 가능
// interface 합치기

// 같은 이름으로 정의가 가능
interface Box {
  width: number;
}
interface Box {
  // 같은이름 사용 가능, 타입 변경은 불가능.
  width: string; // 오류
  height: number;
}

// type은 같은이름 안됨
// type Go = {}
// type Go = {}

// 참고
class Review {
  // 속성 : Property (인스턴스 에 소속)
  getX = (x: string) => {
    return x;
  };
  // 메서드 : Method (프로토타입 에 소속)
  getXY = (x: string) => {
    return x;
  };
}

interface GetXnY {
  // 프로퍼티 형식
  getX: (x: number) => number;
  getY: (y: number) => number;
}

interface GetXnY {
  // 프로퍼티 형식
  getX: (x: number) => number;
  // getY: (x: number) => number;
  // getY: (y: string) => number; // 오류 발생 (매개변수 타입 달라서)
  getY: (y: number) => string; // 오류 발생 (리턴 타입 달라서)
}

// 메소드 방식으로 merging 하기.
interface GetXnYMethod {
  // 프로퍼티 형식
  getXP: (x: number) => number;
  getYP: (y: number) => number;

  // 메서드 방식
  getX(x: number): number;
  getY(y: string): number; // 매개변수 타입 바꿔도 됨.
}

interface GetXnYMethod {
  // 메서드 방식
  getX(x: number): number;
  getY(y: string): number; // 매개변수 타입 바꿔도 됨.
  getY(y: number): string; // 리턴 타입 바꿔도 됨.
  getY(y: number, z: string): string; // 매개변수 개수 바꿔도 됨.
}

const testM: GetXnYMethod = {
  // (parameter) x: number
  getX(x) {
    return x;
  },
  // (parameter) y: string | number
  getY(y) {
    if (typeof y === "string") {
      return y; // string 타입 리턴
    } else {
      return y; // number 타입 리턴
    }
  },
};