
타입스크립트를 하면서 많은 궁금증 중 하나가 언제 interface를 사용하고, 언제 type alias를 사용해야 하는지입니다.
그냥 취향 차이인가? 그냥 팀 컨벤션에 따라가는 건가? 아직 공부만 하는 취준생이라 정확히는 모르겠지만, 최소한 이 둘의 차이 정도는 알고 있어야 할 것 같아서 정리를 해보려고 합니다.
여러 강의나 유투브를 통해 다른분들의 경우 아래와 같이 사용한다고 합니다.
그래서 저는 팀 프로젝트나, 회사 컨벤션에 따라가겠지만 개인프로젝트의 경우 저는 3번의 경우로 사용하려고 하고 있습니다.
1. interface만 사용한다.
2. type alias만 사용한다.
3. 객체의 구조를 나타내는 경우는 interface, 기존의 타입을 재사용하여 새로운 타입을 생성할 때 type alias를 사용
공식문서에 따르면 아래와 같습니다.
You can actually use a type alias to give a name to any type at all, not just an object type. For example, a type alias can name a union type
즉 객체 타입뿐이 아닌 모든 타입에 대하여 새로운 이름을 부여할 때 사용하나 봅니다.
type ID = number | string;
type Sushi = {
calories:number;
salty:boolean;
tasty:boolean
}
공식문서에 따르면 아래와 같습니다.
An interface declaration is another way to name an object type:
즉 객체 타입을 정의할 때 사용하나 봅니다.
interface Sushii {
calories: number;
salty: boolean;
tasty: boolean;
};
type ID = number | string;
type Sushi = {
calories:number;
salty:boolean;
tasty:boolean
}
-----------------
interface Sushii {
calories: number;
salty: boolean;
tasty: boolean;
};
인터페이스의 경우 이름과 범위가 같은 인터페이스가 여러 개 있다면 이들을 자동으로 합쳐지지만(선언 합침), 타입별칭의 경우 에러가 발생한다.// 인터페이스
interface User{
name:string
}
interface User {
age: number;
}
let user : User ={
name:'chiman',
age:3
}
-----------------
// 타입별칭
type User = { // 식별자가 중복되었습니다.
name: string;
}
type User2 = { // 식별자가 중복되었습니다.
age: number;
}
인터페이스의 이름이 같을 경우 한 타입의 프로퍼티와 다른 타입의 프로퍼티가 동일하지 않다면 에러가 발생한다.제네릭들의 선언 방법과 이름까지 똑같아야 합칠 수 있다.interface User {
name: string;
}
interface User {
name: number; // 에러 발생 : name속성은 string 타입이어야함
age: number;
}
let user: User = {
name: 'chiman',
age: 3,
};
---------
// 제네릭
interface User<Age extends number> {
age:Age
}
interface User<Age extends string> { // User의 모든 선언에는 동일한 형식 매개 변수가 있어야 합니다.
age: Age;
}
타입별칭은 (&)연산자를 사용하지만, 인터페이스는 extends를 사용한다.// 인터페이스
interface Food {
calories: number;
salty: boolean;
tasty: boolean;
};
interface Sushi extends Food {
salty: boolean;
};
interface Cake extends Food {
sweet: boolean;
};
------------------------------
// 타입별칭
type Food = {
calories: number;
salty: boolean;
tasty: boolean;
}
type Sushi = Food & {
salty: boolean;
}
type Cake = Food & {
sweet: boolean;
}
// 인터페이스(Interface)
interface MyInterface {
prop1: string;
prop2: number;
}
// 타입 별칭(Type Alias)
type MyTypeAlias = number | string;
interface A {
good(x: number): string;
bad(x: number): string;
}
interface B extends A {
good(x: number | string): string;
bad(x: string): string; // 에러 발생 number 타입은 string에 할당할 수 없음
}
type A = {
good(x: number): string;
bad(x: number): string;
}
type B = A & {
good(x: number | string): string;
bad(x: string): string;
}