
자바스크립트와 타입스크립트에서 객체 데이터를 다루는 것은 일상적인 작업입니다. 특히 React와 같은 현대적인 프레임워크를 사용할 때는 불변성(Immutability)을 유지하며 객체를 업데이트하는 것이 매우 중요합니다.
단순히 obj.key = value와 같이 직접 수정하는 방식은 사이드 이펙트를 유발하고, 리액트의 상태 변경 감지를 방해할 수 있습니다. 또한, 대규모 프로젝트에서 객체의 특정 속성만 안전하게 업데이트(Partial Update)하기 위해서는 타입 시스템의 도움 없이는 런타임 에러를 피하기 어렵습니다.
객체를 안전하게 업데이트하기 위해 우리는 크게 두 가지 도구를 조합합니다.
...): 기존 객체를 복사하면서 새로운 값을 덮어씌워 불변성을 보장합니다.Partial, Pick): 업데이트에 필요한 속성만 타입 수준에서 안전하게 추출하여 관리합니다.type AccountKey = 'id' | 'pwd' | 'nickname'; let myAccount: Record<AccountKey, string> = { id: 'hooney', pwd: '1234aa', nickname: 'hoon' }; // 업데이트할 데이터 (Pick 활용) const dataForUpdating: Pick<Record<AccountKey, string>, 'nickname'> = { nickname: '후니' }; // 💡 새로운 객체를 생성하며 업데이트 myAccount = { ...myAccount, ...dataForUpdating };
실무에서는 어떤 값이 들어올지 모르는 동적인 업데이트 함수를 만들어야 할 때가 많습니다. 이때 Partial<T>는 필수적입니다.
interface UserProfile { id: string; email: string; age: number; bio: string; } /** * Partial을 사용하여 프로필의 일부만 업데이트하는 함수 */ const updateUser = (current: UserProfile, updates: Partial<UserProfile>): UserProfile => { return { ...current, ...updates }; }; const user: UserProfile = { id: '1', email: 'test@test.com', age: 20, bio: 'hello' }; const updated = updateUser(user, { age: 21, bio: 'growing up!' });
Partial<UserProfile>을 사용하면 { age: 21 }만 넘겨도 타입 에러가 발생하지 않으며, 자동 완성과 타입 검사의 이점을 그대로 누릴 수 있습니다.
Immer와 같은 라이브러리를 고려하거나 더 복잡한 Spread 구조가 필요합니다.TypeScript의 유틸리티 타입과 ES6의 문법을 적절히 조합하면, 복잡한 데이터 업데이트 로직도 간결하고 안전하게 작성할 수 있습니다. Pick과 Partial의 차이를 명확히 이해하고 상황에 맞는 도구를 선택하는 습관을 들여보세요!
참고 자료: