TypeScript는 JavaScript에 강력한 타입 시스템을 도입하여 코드의 품질과 가독성을 크게 향상시킬 수 있습니다.
이 글에서는 TypeScript의 주요 고급 타입 시스템과 React Hooks를 사용하는 방법에 대해 자세히 설명하겠습니다.
이러한 기능을 사용하면 더욱 견고하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.
교차 타입 (Intersection Types)
교차 타입이란?
교차 타입은 여러 개의 타입을 하나로 결합하여, 객체가 그 모든 타입의 속성을 가지도록 보장하는 방법을 제공합니다.
이를 통해 다중 상속과 유사한 효과를 얻을 수 있습니다.
interface Person {
name: string;
age: number;
}
interface Employee {
employeeId: number;
department: string;
}
type PersonEmployee = Person & Employee;
const john: PersonEmployee = {
name: "John Doe",
age: 30,
employeeId: 123,
department: "Engineering"
};
위 예시에서는 Person
과 Employee
인터페이스의 모든 속성을 갖는 PersonEmployee
타입을 정의했습니다.
이를 통해 john
객체는 이름, 나이, 직원 ID, 부서를 모두 포함하게 됩니다.
합집합 타입 (Union Types)
합집합 타입이란?
합집합 타입은 변수가 둘 이상의 타입 중 하나일 수 있음을 나타냅니다.
이는 다양한 입력을 처리할 수 있는 유연한 함수를 작성하는 데 유리합니다.
function printId(id: number | string) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
printId("abc123");
printId(101);
이 예시에서는 printId
함수가 숫자 또는 문자열을 받아 처리하는 방법을 보여줍니다.
typeof
를 사용하여 타입을 구분하고 각각에 맞는 처리를 수행합니다.
리터럴 타입 (Literal Types)
리터럴 타입이란?
리터럴 타입은 특정 값, 예를 들어 문자열이나 숫자를 타입으로 사용할 수 있게 해줍니다.
이는 주로 특정 값의 집합을 표현할 때 유용합니다.
type TrafficLight = "red" | "yellow" | "green";
function getSignalDuration(signal: TrafficLight): number {
switch (signal) {
case "red":
return 60;
case "yellow":
return 5;
case "green":
return 45;
}
}
console.log(getSignalDuration("red")); // 60
위의 예시에서 TrafficLight
타입은 신호등의 세 가지 색상 중 하나로 제한되며, 각 색상에 맞는 지속 시간을 반환합니다.
typeof 연산자
typeof란?
typeof
연산자는 변수의 타입을 얻는 데 사용됩니다.
이를 통해 기존 변수 타입을 기반으로 새로운 타입을 정의할 수 있습니다.
let original = { x: 10, y: 20 };
type Point = typeof original;
const newPoint: Point = { x: 5, y: 15 };
여기서 Point
타입은 original
객체의 구조를 따릅니다.
이처럼 typeof
를 사용하면 기존 데이터 구조에 기반한 타입 정의가 가능합니다.
keyof 연산자
keyof란?
keyof
연산자는 객체의 키 타입을 얻는 데 사용됩니다.
이는 객체의 프로퍼티 이름을 타입으로 사용하려는 경우에 유용합니다.
interface Car {
make: string;
model: string;
year: number;
}
type CarKeys = keyof Car; // "make" | "model" | "year"
function logCarProperty(car: Car, key: CarKeys) {
console.log(`Car ${key}: ${car[key]}`);
}
const myCar: Car = { make: "Toyota", model: "Corolla", year: 2020 };
logCarProperty(myCar, "make");
logCarProperty
함수는 Car
객체의 프로퍼티 이름을 받아 해당 프로퍼티 값을 출력합니다.
열거형 (Enum)
열거형이란?
열거형은 관련된 상수들의 집합을 정의하는 데 사용됩니다.
이는 코드의 가독성을 높이고, 상수 값을 쉽게 관리할 수 있게 해줍니다.
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
function getColorName(color: Color) {
return `Color is ${color}`;
}
console.log(getColorName(Color.Red));
위 예시에서 Color
열거형은 세 가지 색상을 정의하며, 각 색상은 문자열 상수로 매핑됩니다.
제네릭 (Generics)
제네릭이란?
제네릭은 클래스, 함수, 인터페이스를 일반화하는 방법입니다.
이를 통해 다양한 타입에 대응하는 코드를 작성할 수 있습니다.
function wrapInArray<T>(arg: T): T[] {
return [arg];
}
const stringArray = wrapInArray("hello");
const numberArray = wrapInArray(123);
wrapInArray
함수는 어떤 타입이든 배열에 감싸 반환합니다.
제네릭을 사용하면 다양한 타입을 동적으로 처리할 수 있습니다.
React Hooks에서의 Props 타입 정의
React 컴포넌트의 Props 타입을 정의함으로써 컴포넌트가 받는 속성의 타입을 명확히 할 수 있습니다.
이는 컴포넌트의 사용과 유지보수를 쉽게 만듭니다.
interface UserProps {
username: string;
age: number;
}
const UserProfile: React.FC<UserProps> = ({ username, age }) => (
<div>
{username} is {age} years old.
</div>
);
이 컴포넌트는 UserProps
인터페이스를 사용하여 username
과 age
속성을 명확히 요구합니다.
React Hooks에서 useState 사용하기
useState
훅은 컴포넌트의 상태 관리를 위해 사용됩니다.
상태의 타입을 지정함으로써 TypeScript의 타입 안전성을 확보할 수 있습니다.
const [count, setCount] = React.useState<number>(0);
const increment = () => setCount(count + 1);
return (
<div>
<p>{count}</p>
<button onClick={increment}>Increment</button>
</div>
);
위 예시에서는 count
의 타입을 number
로 지정하여 상태 관리에 TypeScript의 안전성을 더했습니다.
이벤트 핸들러에서의 데이터 타입
이벤트 핸들러의 인자에 적절한 타입을 지정하면 타입 안전한 이벤트 처리가 가능합니다.
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
console.log(event.currentTarget);
};
return <button onClick={handleClick}>Click me</button>;
이 코드는 버튼 클릭 이벤트를 처리하며, event
인자의 타입을 명시적으로 지정하여 안전성을 높입니다.
요약
TypeScript의 고급 타입 시스템과 React Hooks를 활용하면 더욱 견고하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.
이 글을 바탕으로 이러한 기능을 활용하여 개발 효율성을 높여보세요.
'Javascript' 카테고리의 다른 글
자바스크립트 flatMap 개념 이해하기 (0) | 2024.08.24 |
---|---|
lodash-es보다 가볍고 빠른 es-toolkit으로 전환하기 (0) | 2024.08.24 |
TypeScript로 불필요한 변수 선언 없애기: `satisfies` 활용법 (0) | 2024.08.24 |
TypeScript로 타입을 강화하는 방법: satisfies와 Uppercase<T> 활용하기 (0) | 2024.08.24 |
NextJS 앱 자체 호스팅: 실제 사례로 알아보는 최적의 방법 (0) | 2024.08.09 |