WeniVooks

검색

타입스크립트 베이스캠프

인터페이스

1. 인터페이스

1.1 interface 키워드

객체의 구조를 정의하기 위해 interface 키워드를 사용할 수 있습니다.

interface User {
  id: number;
  name: string;
  info: string;
}
interface User {
  id: number;
  name: string;
  info: string;
}
1.2 선택적 속성

필수가 아닌 속성은 ?를 사용하여 선택적으로 정의할 수 있습니다.

interface User {
  id: number;
  name: string;
  info?: string;
}
 
const user: User = {
  id: 1,
  name: "홍길동"
  // info는 선택사항이므로 생략 가능
};
interface User {
  id: number;
  name: string;
  info?: string;
}
 
const user: User = {
  id: 1,
  name: "홍길동"
  // info는 선택사항이므로 생략 가능
};
1.3 인터페이스 확장

extends 키워드를 사용하여 기존 인터페이스를 확장할 수 있습니다.

interface Character {
  nickName: string;
}
 
interface Bird {
  fly: number;
}
 
interface BirdCharacter extends Character, Bird {
  level: number;
}
 
const birdChar: BirdCharacter = {
  nickName: "Gary",
  fly: 10,
  level: 1
};
interface Character {
  nickName: string;
}
 
interface Bird {
  fly: number;
}
 
interface BirdCharacter extends Character, Bird {
  level: number;
}
 
const birdChar: BirdCharacter = {
  nickName: "Gary",
  fly: 10,
  level: 1
};
1.4 인터페이스 병합

같은 이름의 인터페이스가 같은 스코프에 선언되면 자동으로 병합됩니다.

interface Character {
  nickName: string;
}
 
interface Character {
  level: number;
}
 
// 다음과 동일합니다:
// interface Character {
//   nickName: string;
//   level: number;
// }
 
const char: Character = {
  nickName: "Gary",
  level: 1
};
interface Character {
  nickName: string;
}
 
interface Character {
  level: number;
}
 
// 다음과 동일합니다:
// interface Character {
//   nickName: string;
//   level: number;
// }
 
const char: Character = {
  nickName: "Gary",
  level: 1
};

💡 인터페이스 병합은 전역 인터페이스를 확장할 때 유용하지만, 코드의 명확성을 위해 과도한 사용은 피하는 것이 좋습니다.

1.5 특정 인터페이스 강제

implements는 클래스가 특정 인터페이스의 구조를 따르도록 강제하는 기능입니다.

interface Vehicle {
  start(): void;
  stop(): void;
}
 
// Car 클래스는 Vehicle 인터페이스를 구현해야 함
class Car implements Vehicle {
  start() {
    console.log("차가 출발합니다");
  }
  
  // stop 메서드를 구현하지 않으면 에러 발생!
  // 에러: 'Car' 클래스가 'Vehicle' 인터페이스를 
  // 올바르게 구현하지 않았습니다.
  // 'stop' 속성이 'Car' 형식에 없습니다.
}
interface Vehicle {
  start(): void;
  stop(): void;
}
 
// Car 클래스는 Vehicle 인터페이스를 구현해야 함
class Car implements Vehicle {
  start() {
    console.log("차가 출발합니다");
  }
  
  // stop 메서드를 구현하지 않으면 에러 발생!
  // 에러: 'Car' 클래스가 'Vehicle' 인터페이스를 
  // 올바르게 구현하지 않았습니다.
  // 'stop' 속성이 'Car' 형식에 없습니다.
}
// 올바른 구현
interface Vehicle {
  start(): void;
  stop(): void;
}
 
class Bicycle implements Vehicle {
  start() {
    console.log("자전거가 출발합니다");
  }
  
  stop() {
    console.log("자전거가 멈춥니다");
  }
}
 
// 인스턴스 생성
const bicycle = new Bicycle();
bicycle.start();
// 올바른 구현
interface Vehicle {
  start(): void;
  stop(): void;
}
 
class Bicycle implements Vehicle {
  start() {
    console.log("자전거가 출발합니다");
  }
  
  stop() {
    console.log("자전거가 멈춥니다");
  }
}
 
// 인스턴스 생성
const bicycle = new Bicycle();
bicycle.start();

2. interface와 type의 차이

2.1 확장 방식
// Interface - extends 사용
interface Animal {
  name: string;
}
interface Bear extends Animal {
  honey: boolean;
}
 
// Type - & 사용
type Animal = {
  name: string;
}
type Bear = Animal & {
  honey: boolean;
}
// Interface - extends 사용
interface Animal {
  name: string;
}
interface Bear extends Animal {
  honey: boolean;
}
 
// Type - & 사용
type Animal = {
  name: string;
}
type Bear = Animal & {
  honey: boolean;
}
2.2 선언 병합
  • interface는 같은 이름으로 여러번 선언 가능하며 자동으로 병합됩니다.
  • type은 같은 이름으로 재선언할 수 없습니다.
2.3 사용 권장 사례

타입은 주로 변수에 사용이 됩니다. 함수의 아규먼트, 반환 값, JSON과 같은 형태를 정의할 때 사용합니다. 인터페이스는 객체의 구조를 정의하고 이를 통한 확장을 도모하고자 할 때 사용합니다. JAVA와 같은 객체지향 프로그래밍 언어에서 사용합니다. 요약하자면 아래와 같습니다.

  • interface: 객체의 구조를 정의할 때
  • type: 일반적 변수로 타입을 정의할 때

3. 연습문제

  1. 다음 조건을 만족하는 인터페이스들을 작성해보세요:

    • BaseItem 인터페이스: id(number), name(string) 속성을 가짐
    • Book 인터페이스: BaseItem을 확장하고 author(string), pages(number) 속성을 추가
    • Movie 인터페이스: BaseItem을 확장하고 director(string), duration(number) 속성을 추가
  2. 아래 코드가 정상적으로 동작하도록 필요한 인터페이스를 정의해보세요.

function processUser(user: User): UserDetails {
  return {
    displayName: user.firstName + " " + user.lastName,
    age: user.age,
    isAdmin: user.role === "admin"
  };
}
 
const user = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  role: "admin"
};
 
const details = processUser(user);
function processUser(user: User): UserDetails {
  return {
    displayName: user.firstName + " " + user.lastName,
    age: user.age,
    isAdmin: user.role === "admin"
  };
}
 
const user = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  role: "admin"
};
 
const details = processUser(user);

4. 연습문제 정답

  1. 다음과 같이 인터페이스를 작성할 수 있습니다.
// BaseItem 인터페이스 정의
interface BaseItem {
  id: number;
  name: string;
}
 
// Book 인터페이스 정의 - BaseItem을 확장
interface Book extends BaseItem {
  author: string;
  pages: number;
}
 
// Movie 인터페이스 정의 - BaseItem을 확장
interface Movie extends BaseItem {
  director: string;
  duration: number;
}
 
// 사용 예시
const book: Book = {
  id: 1,
  name: "TypeScript 완벽 가이드",
  author: "위니브",
  pages: 300
};
 
const movie: Movie = {
  id: 2,
  name: "인셉션",
  director: "크리스토퍼 놀란",
  duration: 148
};
// BaseItem 인터페이스 정의
interface BaseItem {
  id: number;
  name: string;
}
 
// Book 인터페이스 정의 - BaseItem을 확장
interface Book extends BaseItem {
  author: string;
  pages: number;
}
 
// Movie 인터페이스 정의 - BaseItem을 확장
interface Movie extends BaseItem {
  director: string;
  duration: number;
}
 
// 사용 예시
const book: Book = {
  id: 1,
  name: "TypeScript 완벽 가이드",
  author: "위니브",
  pages: 300
};
 
const movie: Movie = {
  id: 2,
  name: "인셉션",
  director: "크리스토퍼 놀란",
  duration: 148
};
  1. 다음과 같이 인터페이스를 작성할 수 있습니다.
// User 인터페이스 정의
interface User {
  firstName: string;
  lastName: string;
  age: number;
  role: string;
}
 
// UserDetails 인터페이스 정의
interface UserDetails {
  displayName: string;
  age: number;
  isAdmin: boolean;
}
 
// processUser 함수 사용을 위한 인터페이스들이 모두 정의됨
function processUser(user: User): UserDetails {
  return {
    displayName: user.firstName + " " + user.lastName,
    age: user.age,
    isAdmin: user.role === "admin"
  };
}
 
const user = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  role: "admin"
};
 
const details = processUser(user);
// User 인터페이스 정의
interface User {
  firstName: string;
  lastName: string;
  age: number;
  role: string;
}
 
// UserDetails 인터페이스 정의
interface UserDetails {
  displayName: string;
  age: number;
  isAdmin: boolean;
}
 
// processUser 함수 사용을 위한 인터페이스들이 모두 정의됨
function processUser(user: User): UserDetails {
  return {
    displayName: user.firstName + " " + user.lastName,
    age: user.age,
    isAdmin: user.role === "admin"
  };
}
 
const user = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  role: "admin"
};
 
const details = processUser(user);
2.3 객체와 타입 정의3장 타입스크립트 추가 문법