TypeScript 인터페이스

버터·2025년 6월 2일

인터페이스

객체의 타입을 정의하기 위해 사용한다.

  • 속성은 , 또는 ;으로 구분한다.
  • interface 키워드로 선언하는 사용자 정의 타입이다.
  • 인터페이스를 타입으로 지정한 객체는 해당 인터페이스에 정의된 속성명과 속성의 타입을 준수해야 한다.
  • JS로 컴파일하면 제거된다.
(() => {
  // 인터페이스 생성
  // type User = {
  interface User {
    name: string;
    age: number;
  }

  const u1: User = {
    name: "하루",
    age: 5,
  };
  const u2: User = {
    name: "나무",
    age: 8,
  };

  // 함수의 리턴(객체) 타입으로 인터페이스 지정
  const createUser = function (name: string, age: number): User {
    return { name, age };
  };
  const u3: User = createUser("유저핑", 9);
  console.log(u3);

  // 함수의 매개변수(객체)의 타입으로 인터페이스 지정
  function getAge(user: User): number {
    return user.age;
  }
  console.log(getAge(u1));
  console.log(getAge(u2));
})();
  • 사용
    • 클래스의 타입 지정에 사용한다.
    • 클래스명 뒤에 implements 키워드를 추가한다.
    • 인터페이스를 타입으로 지정한 클래스의 멤버 변수와 메서드는 인터페이스에 정의된 속성과 속성의 타입을 준수해야 한다.
  // HighSchool 클래스가 구현해야 하는 Score 인터페이스 선언
  interface Score {
    kor: number;
    eng: number;
    sum(): number;
    avg(): number;
  }

  // 타입 스크립트 클래스 선언(인터페이스 지정)
  class HighSchool implements Score {
    kor: number;
    eng: number;
    constructor(kor: number, eng: number) {
      this.kor = kor;
      this.eng = eng;
    }
    sum() {
      return this.kor + this.eng;
    }
    avg() {
      return this.sum() / 2;
    }
  }

  // 총점과 평균을 출력하는 함수
  function printScore(score: Score) {
    console.log(score.sum(), score.avg());
  }

  const haru = new HighSchool(100, 90);
  printScore(haru);
})();
  • 선택적 프로퍼티
    • 객체의 속성을 선택적으로 부여하고 싶을 때 인터페이스 속성명 뒤에 ?를 추가한다.
  • 읽기 전용 프로퍼티
    • 인터페이스의 속성명 앞에 readonly 키워드를 추가한다.
    • 객체 생성 시에만 값 할당이 가능하고 생성된 이후에는 수정할 수 없는 속성을 만들 때 사용한다.
(() => {
  // 객체의 인터페이스 정의
  // id는 읽기 전용으로 지정하고 done은 옵셔널로 지정
  interface Todo {
    readonly id: number;
    title: string;
    content: string;
    done?: boolean;
  }

  const todo1: Todo = {
    id: 1,
    title: "할일1",
    content: "내용1",
    done: false,
  };

  const todo2: Todo = {
    id: 2,
    title: "할일2",
    content: "내용2",
  };

  // todo2.id = 3; // readonly 속성 때문에 수정 불가
  todo2.content = "내용3";
})();
  • 상속
    • 부모 인터페이스의 속성과 메서드 정의를 자식 인터페이스가 물려 받고 확장한다.
    • interface 선언부의 extends 키워드 뒤에 상속받을 부모 인터페이스를 지정한다.
  // 할일 등록시 사용
  interface TodoRegist {
    title: string;
    content: string;
  }

  // 할일 상세 조회시 사용
  interface TodoInfo extends TodoRegist {
    // title: string;
    // content: string;
    id: number;
    done: boolean;
  }

  const todo1: TodoRegist = {
    title: "할일1",
    content: "내용1",
  };

  console.log("등록", todo1);

  const todo2: TodoInfo = {
    id: 1,
    title: "할일1",
    content: "내용1",
    done: false,
  };

  console.log("할일 상세 조회", todo2);

인터페이스 상속

  • 계층 구조로 상속
    • 인터페이스 상속은 여러 단계의 계층 구조로 구성할 수 있다.
(() => {
  // 할일 등록시 사용
  interface TodoRegist {
    title: string;
    content: string;
  }

  // 할일 상세 조회시 사용
  interface TodoInfo extends TodoRegist {
    // title: string;
    // content: string;
    id: number;
    done: boolean;
  }

  interface TodoInfoWithDate extends TodoInfo {
    createdAt: Date;
    updatedAt: Date;
  }

  const todo1: TodoRegist = {
    title: "할일1",
    content: "내용1",
  };

  console.log("등록", todo1);

  const todo2: TodoInfo = {
    id: 2,
    title: "할일2",
    content: "내용2",
    done: false,
  };

  console.log("할일 상세 조회", todo2);

  const todo3: TodoInfoWithDate = {
    id: 3,
    title: "할일3",
    content: "내용3",
    done: false,
    createdAt: new Date(),
    updatedAt: new Date(),
  };
})();
  • 다중 상속
    • 둘 이상의 인터페이스를 상속 받는다.
(() => {
  // 할일 등록시 사용
  interface TodoRegist {
    title: string;
    content: string;
  }

  // 할일 목록 조회시 사용
  interface TodoList {
    id: number;
    title: string;
    done: boolean;
  }

  // 할일 상세 조회시 사용
  interface TodoInfo extends TodoRegist, TodoList {
    createdAt: Date;
    updatedAt: Date;
  }

  const todo1: TodoRegist = { title: "할일1", content: "내용1" };
  const todo2: TodoList = { id: 2, title: "할일2", done: true };
  const todo3: TodoInfo = {
    id: 3,
    title: "할일3",
    content: "내용3",
    done: true,
    createdAt: new Date(),
    updatedAt: new Date(),
  };

  console.log(todo1, todo2, todo3);
})();

인터페이스 선언 병합

  • 인터페이스 재선언(선언 병합)
    • 동일한 이름의 인터페이스를 중복으로 선언한다.
    • 기존 인터페이스에 없는 속성을 추가해서 확장한다.
    • 기존 속성과 중복으로 정의는 가능하지만 동일한 타입이어야 한다.
(() => {
  interface Todo {
    id: string;
    title: string;
    content: string;
  }

  interface Todo {
    // id: number; // 동일한 속성을 지정하려면 type이 같아야 함
    title: string; // type이 같다면 동일한 속성도 상관 없음
    done: boolean;
    createAt: Date;
  }

  const todo: Todo = {
    id: "1",
    title: "할일1",
    content: "내용1",
    done: true,
    createAt: new Date(),
  };
})();

타입 별칭과 인터페이스의 차이점

  • 정의할 수 있는 타입 종류
    • 타입 별칭
      • 객체, 클래스, 기본 타입, 유니언 타입, 인터섹션 타입, 유틸리티 타입, 맵드 타입 등의 정의에 사용한다.
      • & 연산자로 확장한다. (인터섹션 타입)
    • 인터페이스
      • 객체, 클래스의 타입을 정의한다.
      • extends 키워드로 확장, 선언 병합한다.
  • 사용
    • 객체의 타입을 지정하는 경우 확장이 용이한 인터페이스 사용을 권장한다.
    • 객체가 아닌 타입 별칭으로만 정의할 수 있는 경우에만 타입 별칭 사용을 권장한다.
profile
프론트엔드 개발자를 꿈꾸는 (구)퍼블리셔

0개의 댓글