🔍 글을 시작하기 전에
해당 글은 타입스크립트 프로그래밍 책과 유데미 타입스크립트 강의를 공부하여 정리한 글입니다.
수정해야 할 부분이 있다면 언제든지 알려주세요!
인터페이스
인터페이스는 객체의 구조(형태)를 설명한다.
타입을 작성하고 값을 할당하려고 하면 인터페이스는 이니셜라이져를 사용할 수 없다는 에러메시지가 뜬다.
이를 통해 인터페이스는 구체적인 값이 있는 구조가 아니라, 객체의 구조를 정의하는 것이라고 할 수 있다.
타입 별칭 vs 인터페이스
1) 기본 구조
// 타입 별칭
type Sushi = {
calories: number
salty: boolean
tasty: boolean
}
// 인터페이스
interface Sushi {
calories: number
salty: boolean
tasty: boolean
}
2) 인터섹션 타입
인터섹션 타입은 다른 타입을 결합하는 것이다.
- 타입 별칭
type Admin = {
name: string;
privileges: string[];
};
type Employee = {
name: string;
startDate: Date;
};
type ElevatedEmployee = Admin & Employee;
const e1: ElevatedEmployee = {
name: 'Max',
privileges: ['create-server'],
startDate: new Date(),
};
- 인터페이스
// 1번
interface Admin {
name: string;
privileges: string[];
};
interface Employee {
name: string;
startDate: Date;
};
type ElevatedEmployee = Admin & Employee;
const e1: ElevatedEmployee = {
name: 'Max',
privileges: ['create-server'],
startDate: new Date(),
};
// 2번
interface Admin {
name: string;
privileges: string[];
}
interface Employee {
name: string;
startDate: Date;
}
interface ElevatedEmployee extends Admin, Employee {}
const e1: ElevatedEmployee = {
name: 'Max',
privileges: ['create-server'],
startDate: new Date(),
};
3) 중복되는 프로퍼티를 공통 정보로 정의한 구조
// 타입 별칭
type Food = {
calories: number
tasty: boolean
}
type Cake = Food & {
sweet: boolean
}
// 인터페이스
interface Food {
calories: number
tasty: boolean
}
interface Cake extends Food {
sweet: boolean
}
4) 함수 타입 정의
// 타입 별칭
type AddFn = (a: number, b:number) => number
const add: AddFn = (x: number, y: number) => x + y;
console.log(add(1,3)); // 4
// 인터페이스
interface AddFn {
(a: number, b:number): number
}
const add: AddFn = (x: number, y: number) => x + y;
console.log(add(1,3)); // 4
5) 차이점
1. 오른편에 올 수 있는 형태
타입 별칭의 오른쪽엔 타입 표현식을 포함한 모든 타입이 올 수 있으나
type A = number
type B = A | string
인터페이스의 오른쪽엔 반드시 형태가 나와야 한다.
2. 상위 타입의 상속
인터페이스는 상속받는 인터페이스 타입에 상위 인터페이스를 할당할 수 있는지 확인하며
타입 별칭은 확장하는 타입을 최대한 조합하여, 상위 타입을 오버로드 하기도 한다.
A의 bad함수의 x는 number, B의 bad함수의 x는 string일 경우
number 타입은 string 타입에 할당할 수 없다며 B는 A를 올바르게 상속받지 않는다는 오류를 발생시킨다.
객체 타입의 상속을 표현할 땐 인터페이스를 사용하여 에러를 쉽게 감지할 수 있다.
interface A {
good(x: number): string
bad(x: number): string
}
interface B extends A {
good(x:number | string): string
bad(x: string): string
}
위 인터페이스 정의를 타입 별칭으로 바꾸면 다음과 같이 바꿀 수 있는데,
A의 bad 함수 타입 정의를 오버로드한 시그니처가 만들어지게 되어 오류가 발생하지 않는다.
type A = {
good(x: number): string
bad(x: number): string
}
type B = A & {
good(x:number | string): string
bad(x: string): string
}
3. 선언 합침
이름과 범위가 같은 인터페이스가 여러 개 있다면 자동으로 합쳐지며
타입 별칭은 같은 조건일 때 컴파일 에러가 발생한다.
선언 합침
name 프로퍼티를 가진 User 인터페이스를 정의하고,
age 프로퍼티를 가진 User 인터페이스를 정의하면 다음과 같다.
interface User {
name: string
}
interface User {
age: number
}
User 인터페이스의 타입으로 지정한 변수 a를 살펴보면,
let a: User = {
name: '재영', // Error: age 프로퍼티가 없음
}
let a: User = {
name: '재영',
age: 100
}
위와 같이 name, age 프로퍼티를 모두 작성해야 하는 것을 확인할 수 있었다.
타입 별칭을 사용하여 이름을 같게 정의한다면 에러가 발생하는 것을 확인했다.
type Person = {
name: string // Error: 중복 식별자 Person
}
type Person = {
age: number // Error: 중복 식별자 Person
}
implements
implements
를 사용하여 특정 인터페이스를 타입으로 지정한 클래스를 선언할 수 있다.
이때 인터페이스에서 선언한 모든 메서드를 구현해야 한다.
(추가 속성이 필요하다면 메서드나 프로퍼티를 오버로드하여 구현할 수 있다.)
만약 프로퍼티를 정의한다면, private, protected, public, static
키워드는 사용할 수 없고
readonly
키워드는 사용할 수 있다.
찾아보니 private, protected, public, static
키워드는 클래스 구현과 관련되어 있는데
인터페이스는 다양한 클래스에서 공통적으로 사용되는 메서드와 속성의 형태를 정의하는 것이 목적이지
클래스의 구현과는 상관이 없기 때문이라고 한다.
interface Animal {
readonly name: string
eat(food: string): void
sleep(hours: number): void
}
class Cat implements Animal {
name = '은동'
eat(food: string) {
console.log(food, '를 먹었다냥')
}
sleep(hours: number) {
console.log(hours, '시간 잔다냥')
}
}
'Front-End > TypeScript' 카테고리의 다른 글
타입스크립트[TypeScript] | jest로 DOM 테스트 하기위해 필요한 환경 설정 (0) | 2023.06.15 |
---|---|
타입스크립트[TypeScript] | TS 환경에 jest 설정하기 (0) | 2023.06.13 |
타입스크립트[TypeScript] | 4장 연습 문제 (0) | 2023.04.24 |
타입스크립트[TypeScript] | 제네릭(Generic) 제약조건 설정하기 (0) | 2023.04.24 |