Web/JS

유연성과 안전성을 동시에! TypeScript Map Pattern 활용법

이영훈닷컴 2025. 4. 2. 09:03
728x90

TypeScript로 프로젝트를 진행하다 보면, 특정 데이터 구조를 처리할 때 유연성과 유지보수성을 동시에 고민하게 되는 경우가 많습니다. 특히, 여러 곳에서 참조되는 타입 정의를 변경해야 할 때, 반복적인 수정과 오류 가능성이 증가하죠. 오늘은 이러한 문제를 해결하기 위한 ‘Map Pattern’을 활용한 설계 개선 방법을 소개합니다.

문제점

기존의 데이터 구조는 아래와 같았습니다:

typescript
// FinalResponse.ts
export type FinalResponse = {
totalScore: number;
reactions: {
likes: Reaction;
unicorns: Reaction;
explodingHeads: Reaction;
raisedHands: Reaction;
fire: Reaction;
};
};

여기서 Reaction은 다음과 같이 정의되었습니다:

typescript
// Reaction.ts
export type Reaction = {
count: number;
percentage: number;
};

이 구조는 기본적으로 잘 작동했지만, 새로운 반응(예: ‘hearts’, ‘claps’)을 추가해야 할 경우 여러 파일을 수정해야 했습니다. 이는 코드의 결합도를 높이고, 실수할 가능성을 키우는 단점이 있습니다.

해결책: Map Pattern

기존 구조의 한계를 극복하기 위해, Record을 활용한 ‘Map Pattern’을 도입했습니다:

typescript
// FinalResponse.ts
export type ReactionMap = Record;
export type FinalResponse = {
totalScore: number;
reactions: ReactionMap;
};

이제 ‘reactions’ 필드는 동적으로 키를 추가할 수 있는 유연한 구조로 변경되었습니다. 따라서 새로운 반응을 추가하려면 단순히 해당 키와 값을 추가하면 됩니다.

더 안전한 접근법

하지만, 너무 유연한 구조는 잘못된 데이터를 허용할 위험이 있습니다. 이를 방지하기 위해, 허용 가능한 반응의 키를 미리 정의하는 방식으로 개선했습니다:

typescript
// FinalResponse.ts
type AllowedReactions = ‘likes’ | ‘unicorns’ | ‘explodingHeads’ | ‘raisedHands’ | ‘fire’;
export type ReactionMap = { [key in AllowedReactions]: Reaction };
export type FinalResponse = {
totalScore: number;
reactions: ReactionMap;
};

이 방식은 새로운 반응을 추가하려면 AllowedReactions 타입만 수정하면 되므로, 코드의 유지보수성이 높아지고 실수를 줄일 수 있습니다.

장점

  1. 유연성: 새로운 반응을 쉽게 추가할 수 있습니다.
  2. 안전성: 허용된 키만 사용할 수 있도록 제한합니다.
  3. OCP 준수: 기존 코드를 수정하지 않고 기능을 확장할 수 있습니다.

결론

Map Pattern은 TypeScript에서 데이터 구조를 더욱 유연하고 안전하게 설계할 수 있는 강력한 도구입니다. 이 패턴을 활용하면 코드의 유지보수성을 높이고, 실수를 방지하면서도 확장성을 확보할 수 있습니다. 다음 프로젝트에서 이 패턴을 적용해 보세요!

728x90