Electronic Jeremy Record

[Typescript] type vs interface 언제 써야하는가? 본문

기술의기록

[Typescript] type vs interface 언제 써야하는가?

Jeremy Winchester 2022. 8. 16. 23:51
반응형

커스텀 타입을 선언할 때 일반적으로 type을 사용한다.

다만 object의 타입을 선언할 땐 하나의 선택지가 더 있다.

바로 interface 다.

 

type과 interface는 표면적으로는 같은 역할을 한다.

이들의 사용 방법은 다음과 같다.

 

샘플의 객체를 생성했다.

const student = {
    name : 'kevin',
    age: 15,
    hasCar : false
}

이 객체의 타입을 위의 두 가지 방식으로 선언해보겠다.

 

type 방식

type StudentTypeCase = {
    name: string;
    age: number;
    hasCar: boolean;
}

const student:StudentTypeCase = {
    name : 'kevin',
    age: 15,
    hasCar : false
}

interface 방식

interface StudentInterfaceCase {
    name: string;
    age: number;
    hasCar: boolean;
}

const student:StudentInterfaceCase = {
    name : 'kevin',
    age: 15,
    hasCar : false
}

이 둘이 student 객체의 타입을 선언하는 역할은 동일하다. 

그럼 interface의 존재는 무엇일까? 왜 type으로 이 역할을 할 수 있는데 굳이 interface가 있는 이유가 무엇일까?

대표적으로 interface는 상속을 할 수 있다. 그 상속을 어떻게 하는가? 먼저 샘플을 추가해보겠다.

 

interface StudentInterfaceCase {
	name: string;
	age: number;
	hasCar: boolean;
}

const student: StudentInterfaceCase = {
	name: "kevin",
	age: 15,
	hasCar: false,
};

const teacher = {
	name: "julia",
	age: 35,
	hasCar: true,
	subject: "science",
	pay: 500,
};

teacher의 객체를 추가했고, 이 객체의 타입도 지정해보겠다. 

interface StudentInterfaceCase {
	name: string;
	age: number;
	hasCar: boolean;
}
interface TeacherInterfaceCase {
	name: string;
	age: number;
	hasCar: boolean;
	subject: string;
	pay: number;
}
const student: StudentInterfaceCase = {
	name: "kevin",
	age: 15,
	hasCar: false,
};
const teacher: TeacherInterfaceCase = {
	name: "julia",
	age: 35,
	hasCar: true,
	subject: "science",
	pay: 500,
};

사실상 이 타입은 문제는 없다.

다만 중복되는 name, age,hasCar는 앞서 말한 상속으로 좀 더 간편하고 간단하게 타입을 만들 수 있다.

interface StudentInterfaceCase {
	name: string;
	age: number;
	hasCar: boolean;
}
//StudentInterfaceCase를 상속 받아 teacherInterfaceCase를 생성
interface TeacherInterfaceCase extends StudentInterfaceCase {
	subject: string;
	pay: number;
} 
const student: StudentInterfaceCase = {
	name: "kevin",
	age: 15,
	hasCar: false,
};
const teacher: TeacherInterfaceCase = {
	name: "julia",
	age: 35,
	hasCar: true,
	subject: "science",
	pay: 500,
};

teacher에 새롭게 추가 되는 subject와 pay만 선언해서 teacher 객체의 타입을 선언하였다. 

이처럼 interface는 상속을 통해 마치 클래스로 객체 지향 코드를 만드는 것처럼 타입을 만들 수가 있다.

 

그런데 재밋는건 

이 상속의 효과 같은 것을 type도 할 수 있다는 것이다. 

type StudentTypeCase = {
	name: string;
	age: number;
	hasCar: boolean;
};
//TeacherTypeCase를 만들고 StudentTypeCase를 결합
type TeacherTypeCase = {
	subject: string;
	pay: number;
} & StudentTypeCase;

const student: StudentTypeCase = {
	name: "kevin",
	age: 15,
	hasCar: false,
};
const teacher: TeacherTypeCase = {
	name: "julia",
	age: 35,
	hasCar: true,
	subject: "science",
	pay: 500,
};

&기호를 써서 2개의 타입을 결합시키는 것을 intersection type 이라고 한다.

이처럼 intersection type은 마치 interface의 extends처럼 사용할 수 있다.

 

그러면 왜 굳이 interface가 있을까?

 

type과 interface는 유연성이 다르다. 

하나의 예로 interface는 중복 선언이 가능하지만 type은 중복 선언이 불가능하다(에러 난다.)

interface를 중복 선언하면 extends 한 것 마냥 선언된 객체가 하나도 합쳐진다. 

pay 의 타입이 없어 에러가 날 때
재선언하여 타입을 추가할 수 있다(실제로 이렇게 사용되진 않는다!)

 

즉,

type vs interface의 답은 

기능에 있어서 큰 차이가 없지만

오프소스처럼 내가 선언한 타입이 여기저기 다양하게 쓰임새가 있을 때

type 보다는 interface가 더 적절한 사용이라고 볼 수 있으며

타입의 변동을 제한하고 싶을 때 type을 사용하는 것이 적절하다고 볼 수 있다.

 

 

 

반응형