최종 수정 : 2024-05-28
인터페이스(Interface)
타입에 이름을 지어주는 또 다른 문법이다. 또한 객체의 구조를 정의하는데 특화된 문법이다. 이에 따라, 상속 및 병합 등의 특수한 기능을 제공한다.
인터페이스(interface)라는 뜻은 '상호간에 약속된 규칙'이라는 뜻이다. 그래서 프론트엔드 개발과 백엔드 개발로 나누어 웹 애플리케이션을 만들 때, 서버에서 어떻게 데이터를 줄지 정하는 작업을 '인터페이스를 맞춘다'고 표현하기도 한다.
메서드 오버로딩
인터페이스로 타입을 정의할 수 있는 부분
1) 객체의 속성과 속성 타입
인터페이스의 타입과 맞지 않는 객체에 인터페이스를 지정한다면 에러가 발생한다.
interface Book {
name: string;
page: number;
}
let TypeScript: Book { name: '타입스크립트', page: 462 };
// Error
let JavaScript: Book { name: '자바스크립트', page: 734, hobby: '개발' };
2) 함수의 파라미터와 반환 타입
- 객체는 함수의 파라미터로도 사용되고 반환값으로도 사용될 수 있다.
interface Book {
name: string;
page: number;
}
function countPage(random: Book) {
console.log(random.page);
}
let typescript = { name: '타입스크립트', page: 643 };
countPage(typescript); // 643
- 함수의 반환 타입을 인터페이스로 정의
interface Book {
name: string;
page: number;
}
function getBook(random: Book): Book {
return random;
}
3) 함수의 스펙(파라미터 개수와 반환값 여부 등)
4) 배열과 객체를 접근하는 방식
5) 클래스
인터페이스의 옵션 속성
- 인터페이스로 정의된 객체의 속성을 선택적으로 사용
- 상황에 따라서 유연하게 인터페이스 속성의 사용 여부를 결정할 수 있다.
interface Book {
name?: string;
page: number;
}
function someBook(random: Book) {
console.log(random.page);
}
let typescript = { page: 645 };
someBook(typescript); // 645
인터페이스의 확장
- 타입 정의를 확장시킬 수 있다.
- 상속 : 객체 간 관계를 형성하는 방법, 상위(부모) 클래스의 내용을 하위(자식) 클래스가 물려받아 사용하거나 확장하는 기법
interface Book {
name: string;
page: number;
}
interface Athor extnds Book {
athor: string;
}
// 사실상 이런 인터페이스가 된 것과 같다.
interface Athor {
name: string;
page: number;
athor: string;
}
let typescript: Athor = {
name: '타입스크립트',
page: 679,
athor: 'teadyeong'
}
참고 사항
- 부모 인터페이스에서 상속받은 속성의 타입을 자식 인터페이스에서 다르게 정의하면 에러가 발생한다.
- 여러번 상속 할 수 있다.
다중 확장이 가능하다.
선언 병합
타입 선언과 달리 같은 이름의 인터페이스를 선언해도 오류가 발생하지 않으며, 합쳐진다. 두 인터페이스의 프로퍼티의 타입이 같을 때는 병합되지만, 다를 경우에는 충돌이 발생한다.
개발을 할 때보다는 라이브러리의 타입이 부실하여 추가할 때 주로 사용한다.
interface Person {
name: string;
}
interface Person {
name: string;
age: number;
}
interface Developer extends Person {
name: 'hello';
}
const person: Person = {
name: '',
age: 33,
};
인터페이스를 이용한 인덱싱 타입 정의
인덱싱 : 객체의 특정 속성을 접근하거나 배열의 인덱스로 특정 요소에 접근하는 동작
let person = {
name: 'taeadyeong',
age: 32
};
console.log(person['name']); // taedyeong
let books = ['A', 'B', 'C']'
console.log(books[0]); // A
1) 배열 인덱싱 타입 정의
interface BookList {
[index: number]: string;
}
let books: BookList = ['A', 'B', 'C']
books[0] // A
books[1] // B
2) 객체 인덱싱 타입 정의
// 속성 이름 - 문자열
// 속성 값 - 숫자
interface BookPage {
[name: string]: number;
}
let book: BookPage = {
typescript: 785
}
let page = book[typescript]; // 785
let page = book.typescript; // 785
// 속성 이름 - 문자열
// 속성 값 - 문자열
interface BookPage {
[name: string]: string;
}
let book: BookPage = {
typescript: '785',
}
let page = book['typescript']; // 785
속성 이름에 숫자나 - 등 특수 기호가 들어가면 '점표기법'으로는 접근할 수 없기 때문에 '대괄호 표기법' 방식으로 접근해야 한다.
인터페이스와 인터섹션의 가장 큰 차이점
인터섹션은 두 가지 이상의 타입을 한 번에 합칠 수 있다. 물론, 인터페이스도 가능하다. 그러나 좀 더 지저분한 느낌이다.
// Interface
interface Entity {
id: string;
}
interface TimestampEntity extends Entity {
createdAt: Date;
updatedAt: Date;
}
interface User extends Entity {
username: string;
email: string;
}
// 타입 별칭
type Entity = {
id: string;
createdAt: Date;
updatedAt: Date;
}
type User = Entity & {
username: string;
email: string;
}
대부분의 경우 Interface와 타입 별칭을 둘 다 사용할 수 있다. 하지만 되도록 Interface의 목적에 맞는 경우라면 Interface를 사용하는 게 좋다.
'프론트엔드 > TS 공부' 카테고리의 다른 글
이넘(enum) (0) | 2023.07.26 |
---|---|
타입 별칭(type alias) / 인덱스 시그니처(index signature) (0) | 2023.07.26 |
리터럴 타입(literal type) / 유니언 타입(union type) / 인터섹션 타입(intersection type) (0) | 2023.07.26 |
변수와 함수의 타입 정의 (0) | 2023.07.25 |
타입스크립트란? (0) | 2023.07.25 |
댓글