인터페이스
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. 연습문제
-
다음 조건을 만족하는 인터페이스들을 작성해보세요:
BaseItem
인터페이스: id(number), name(string) 속성을 가짐Book
인터페이스:BaseItem
을 확장하고 author(string), pages(number) 속성을 추가Movie
인터페이스:BaseItem
을 확장하고 director(string), duration(number) 속성을 추가
-
아래 코드가 정상적으로 동작하도록 필요한 인터페이스를 정의해보세요.
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. 연습문제 정답
- 다음과 같이 인터페이스를 작성할 수 있습니다.
// 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
};
- 다음과 같이 인터페이스를 작성할 수 있습니다.
// 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);