반응형
TypeScript에서는 props 타입을 선언할 때 type
과 interface
를 사용한다
둘 다 타입을 선언한다는 공통점이 있지만 이 둘은 다르다
type
객체 타입 뿐 아니라 모든 타입에 대해 새로운 이름을 붙일 수 있다
// 예문
type TUser = {
id: number;
name: string;
};
const typeUser: TUser = {
id: 0,
name: '김하나',
};
interface
객체 타입을 만드는 또 다른 방법이다
// 예문
interface IUser = {
id: number;
name: string;
};
const interfaceUser: IUser = {
id: 0,
name: '김하나',
};
확장하기
// interface 확장하기
interface IUser {
id: number
name: string
}
interface IUser2 extends IUser {
age: number
}
// type 확장하기
type TUser = {
id: number
name: string
}
type TUser2 = TUser & {
age: number
}
차이점(선언 병합)
type
과 interfece
는 매우 유사하기에 둘 중 하나를 선택하여 사용할 수 있지만 interface
가 가지는 대부분의 기능은 type
에서도 동일하게 사용 가능하다
이 둘의 차이점은 type
은 새 속성을 추가하기 위해 동일한 이름으로 선언할 수 없는 반면, interface
는 새 속성을 확장할 수 있다는 점이다
// interface 선언 병합
interface IUser {
id: number
name: string
}
interface IUser {
age: number
}
const user1: IUser = {
id: 0,
name: '김하나',
age: 20,
};
// type 선언 병합
type TUser = {
id: number
name: string
};
type TUser = {
age: number
};
// Error: Duplicate identifier 'TUser'.
// type은 생성된 뒤에는 달라질 수 없다
type
이름이 오류 메세지는 경우에 따라 나타날 수도 있고 아닐 수도 있지만 interface
는 항상 오류 메세지에 이름이 나타난다(참고)
// Compiler error messages will always use
// the name of an interface:
interface Mammal {
name: string
}
function echoMammal(m: Mammal) {
console.log(m.name)
}
// e.g. The error below will always use the name Mammal
// to refer to the type which is expected:
echoMammal({ name: 12343 })
// When a type hasn't gone through any form of manipulation
// then you still get the name as a reference:
type Lizard = {
name: string
}
function echoLizard(l: Lizard) {
console.log(l.name)
}
// So this still refers to Lizard
echoLizard({ name: 12345})
// But when a a type has been transformed, for example via this
// Omit then the error message will show the resulting type
// and not the name
type Arachnid = Omit<{ name: string, legs: 8 }, 'legs'>
function echoSpider(l: Arachnid) {
console.log(l.name)
}
echoSpider({ name: 12345, legs: 8})
type
은 선언 병합에 포함될 수 없지만 interface
는 선언 병합에 포함될 수 있다
// An interface can be re-opened
// and new values added:
interface Mammal {
genus: string
}
interface Mammal {
breed?: string
}
const animal: Mammal = {
genus: "1234",
// Fails because breed has to be a string
breed: 1
}
type Reptile = {
genus: string
}
// You cannot add new variables in the same way
type Reptile = {
breed?: string
}
interface
는 객체를 선언하는 데에만 사용된다
// Here's two examples of
// using types and interfaces
// to describe an object
interface AnObject1 {
value: string
}
type AnObject2 = {
value: string
}
// Using type we can create custom names
// for existing primitives:
type SanitizedString = string
type EvenNumber = number
// This isn't feasible with interfaces
interface X extends string {
}
interfeace
는 항상 있는 그대로 오류 메세지에 나타난다
단, 해당 interface
가 이름으로 사용되었을 때에만 해당한다
// Compiler error messages will always use
// the name of an interface:
interface Mammal {
name: string
}
function echoMammal(m: Mammal) {
console.log(m.name)
}
// e.g. The error below will always use the name Mammal
// to refer to the type which is expected:
echoMammal({ name: 12343 })
// The type of `m` here is the exact same as mammal,
// but as it's not been directly named, TypeScript
// won't mention it in the error messaging
function echoAnimal(m: { name: string }) {
console.log(m.name)
}
echoAnimal({ name: 12345 })
대부분의 경우 개인적 선호에 따라 type
과 interface
중에서 선택 사용할 수 있지만
공식문서에는 interfeace
를 사용하고 이후 문제가 발생하였을 때 type
을 사용하기를 권한다
반응형