TypeScript의 타입 시스템을 이해하는 데 어려움을 겪고 있는 스타터에게 도움이 될 만한 접근 방식이 있다. 바로 TypeScript의 타입을 "집합(Set)"으로 생각하는 것이다. 이 방법은 TypeScript의 여러 기능을 더 쉽게 이해하고, 복잡한 타입을 다루는 데 도움이 된다.
TypeScript의 타입을 데이터의 "집합"으로 생각할 수 있다. 예를 들어,
string
타입은 모든 가능한 문자열의 집합이고,number
타입은 모든 가능한 숫자의 집합이다. 이런 방식으로 타입을 집합으로 이해하면, 타입 연산이 어떻게 작동하는지 더 명확하게 파악할 수 있다.
TypeScript에서 교차(&) 연산자를 사용하면 여러 타입을 결합하여 새로운 타입을 만들 수 있다. 이 연산자는 두 개 이상의 타입을 결합하여 공통 속성을 가지는 객체를 만드는 데 유용하다.
예를 들어,
type Foo = { x: number } & { y: number }
는x
와y
속성을 모두 포함하는 객체를 만드는 것이다. 여기서 & 연산자는 두 타입을 결합해, 각각의 속성을 모두 포함하는 타입을 생성한다.
type Person = { name: string };
type Employee = { employeeId: number };
type EmployeeDetails = Person & Employee;
const employee: EmployeeDetails = {
name: "Alice",
employeeId: 1234
};
위 코드에서 EmployeeDetails
타입은 Person
과 Employee
타입의 속성을 모두 포함하므로, name
과 employeeId
속성이 모두 필요하다.
합집합(|) 연산자는 두 타입의 가능한 값을 모두 포함하는 타입을 만든다. 예를 들어,
type Bar = { x: number } | { y: number }
는{ x: number }
또는{ y: number }
를 가질 수 있는 타입을 생성한다. 이때, 주어진 값은 두 타입 중 하나의 조건을 만족하면 된다.
TypeScript에서
extends
키워드를 사용하면 한 타입이 다른 타입의 부분 집합인지 확인할 수 있다. 이를 통해 특정 조건을 만족하는지에 따라 다른 타입을 반환하는 기능을 구현할 수 있다.
type IntrospectFoo = number | null | string extends number
? "number | null | string은 number의 부분 집합이다"
: "number | null | string은 number의 부분 집합이 아니다";
이 코드는 number | null | string
이 number
타입의 부분 집합이 아님을 확인해준다.
& 연산자는 다양한 상황에서 활용될 수 있다. 아래는 이 연산자를 활용한 예시들이다:
객체 타입 결합: 서로 다른 타입을 결합해 더 복잡한 타입을 만든다.
type Person = { name: string };
type Employee = { employeeId: number };
type EmployeeDetails = Person & Employee;
const employee: EmployeeDetails = {
name: "Alice",
employeeId: 1234
};
함수 반환 타입 결합: 여러 함수를 조합하여 하나의 객체를 반환할 때 유용하다.
function getName() {
return { name: "Alice" };
}
function getJob() {
return { job: "Engineer" };
}
// getName 함수의 반환값과 getJob 함수의 반환값을 합친 객체를 반환한다.
type PersonWithJob = ReturnType<typeof getName> & ReturnType<typeof getJob>;
const person: PersonWithJob = {
// getName 함수의 반환값을 person 객체에 복사한다.
...getName(),
// getJob 함수의 반환값을 person 객체에 복사한다.
...getJob()
};
다형성을 이용한 교차 타입: 조건부 타입과 & 연산자를 결합하여 더 정교한 타입을 생성한다.
type Admin = { role: "admin" };
type User = { role: "user" };
type Access = { canAccess: boolean };
type AdminAccess = (Admin | User) & Access;
const adminUser: AdminAccess = {
role: "admin",
canAccess: true
};
TypeScript를 집합으로 생각하면, 타입 시스템을 이해하고 활용하는 데 큰 도움이 된다. & 연산자를 활용하면 다양한 상황에서 복잡한 타입을 결합해 더 안전하고 명확한 코드를 작성할 수 있다. 이러한 접근 방식을 통해 TypeScript의 복잡한 기능도 더 쉽게 다룰 수 있을 것이다.