[Typescript]언제 interface와 type을 사용해야 하나?
TypeScript
에서 interface
와 type
은 모두 객체의 형태와 동작을 정의하는 데 사용되지만, 경우에 따라 적절한 것을 사용하면 코드 가독성과 유지 관리에 있어 차이를 만들 수 있습니다. 이 글에서는 interface
와 type
을 구분해 사용하는 적절한 경우에 대해 살펴보겠습니다.
1. 객체의 형태 정의
interface: 객체의 구조를 정의해야 할 때나 클래스에서 구현할 수 있는 계약을 정의할 때 사용합니다. 특히 클래스에 의해 확장되거나 구현될 수 있는 것이 필요할 때 객체를 표현하는 데 이상적입니다.
interface Animal {
species: string;
age: number;
}
const animal: Animal = {
species: 'Tiger',
age: 5,
};
type: 좀 더 복잡한 형태를 정의하거나, 여러 곳에서 공통적으로 사용될 때, 또는 나중에 유형을 결합해야 하는 경우(교집합, 합집합)처럼 더 많은 유연성이 필요할 때 사용하는 것이 좋습니다.
type Animal = {
species: string;
age: number;
};
2. 객체 확장
interface: 특히 대규모 프로젝트에서 객체 유형을 여러 번 확장해야 하는 경우 사용합니다. extends
구문은 명확하고 직관적이어서 코드를 읽고 유지 관리하기가 더 쉽습니다.
interface Animal {
species: string;
age: number;
}
interface Mammal extends Animal {
furType: string;
}
const lion: Mammal = {
species: 'Lion',
age: 5,
furType: 'Short',
};
type: 직접 상속이 필요하지 않은 경우 교차연산자(&
)을 사용하여 유형을 결합하는 데 사용됩니다. 특히 복잡한 유형에서 유형을 명시적으로 결합하는 데 이상적입니다.
type Animal = {
species: string;
age: number;
};
type Mammal = Animal & {
furType: string;
};
const tiger: MammalType = {
species: 'Tiger',
age: 4,
furType: 'Striped',
};
3. 정의 병합
interface: 타사 라이브러리를 사용하거나 대규모 시스템에서 약속을 정의하는 경우처럼 유형 정의를 자동으로 병합해야 하는 경우 사용합니다. 이는 이미 정의된 유형을 확장할 수 있는 모듈과 라이브러리 작업을 할 때 유용합니다.
interface Animal {
species: string;
}
interface Animal {
age: number;
}
const animal: Animal = {
species: 'Dog',
age: 3,
};
type: TypeScript는 type에 대해 유형 정의에 대한 병합을 허용하지 않기 때문에, 자동 병합이 필요한 경우에는 사용을 피해야 합니다.
//허용되지 않음:
type Animal = {
species: string;
};
type Animal = {
age: number;
}; // Error: Duplicate identifier 'Animal'.
4. 클래스와 구현
interface: 객체 지향 프로그래밍 시나리오에서 클래스에 대한 약속을 정의할 때 사용합니다.
interface Animal {
species: string;
age: number;
}
class Mammal implements Animal {
species: string;
age: number;
constructor(species: string, age: number) {
this.species = species;
this.age = age;
}
}
type: 클래스를 구현하는 데 사용하는 것은 피하는 것이 좋습니다. interface를 사용하는 것이 더 직관적이고 이 목적에 더 잘 지원됩니다.
// 추천하지 않는 방법
type Animal = {
species: string;
age: number;
};
class Mammal implements Animal {
species: string;
age: number;
constructor(species: string, age: number) {
this.species = species;
this.age = age;
}
}
5. 복합 유형: Union과 Intersection
type: interface에서는 제공하지 않는 합집합 및 교집합과 같은 복잡한 유형을 만드는 데 사용합니다.
Union의 예:
type AnimalState = 'sleeping' | 'eating' | 'hunting';
const currentAnimalState: AnimalState = 'eating';
Intersection 예:
// 동물의 특성에 대한 타입 정의
type MammalTraits = {
furType: string;
};
type PredatorTraits = {
prey: string;
};
// 포유류와 포식자의 특성을 모두 가진 타입 정의
type PredatorMammal = MammalTraits & PredatorTraits;
// 타입을 활용한 객체 생성 예제
const lion: PredatorMammal = {
furType: 'Short',
prey: 'Deer',
};
요약
-
interface
를 사용하는 경우- 객체 구조를 정의하고, 클래스에 의해 객체가 확장되거나 구현될 것으로 예상되는 경우.
- 자동 정의 병합이 필요한 경우
- 클래스 계약을 정의할 때.
-
type
을 사용하는 경우- 합집합, 교집합 및 더 복잡한 유형에 사용됩니다.
- 동적 유형을 만드는 데 유연성이 필요한 경우
- 유형을 명시적으로 결합하려는 경우.