logo hsb.horse
← 스니펫 목록으로 돌아가기

Snippets

프로퍼티 추출 헬퍼 함수

객체에서 지정된 프로퍼티만 추출하는 함수를 생성합니다. 중첩된 mapBy와 배열 변환에서 타입 안전한 프로퍼티 추출을 한 줄로 작성할 수 있습니다.

게시일: 수정일:

배열을 map으로 변환할 때 전체 객체가 아닌 특정 프로퍼티만 필요한 경우가 많습니다. 인라인으로 작성하면 장황해지기 쉽지만, 프로퍼티 추출 함수를 미리 정의해두면 map(propsExtractor('id', 'name'))와 같은 간결한 표현이 가능합니다.

코드

type LiteralObject = Record<string, unknown>
/**
* 객체에서 지정된 프로퍼티만 추출하는 함수를 생성합니다
*/
export function propsExtractor<
Props extends LiteralObject,
PropKey extends keyof Props,
>(
...props: PropKey[]
): (obj: Props) => Pick<Props, PropKey> {
return (obj: Props) => {
const result: Partial<Props> = {}
for (const prop of props) {
if (Object.hasOwn(obj, prop)) {
result[prop] = obj[prop]
}
}
return result as Pick<Props, PropKey>
}
}

사용 예시

type User = {
id: string
name: string
email: string
role: string
createdAt: Date
}
const users: User[] = [
{ id: '1', name: 'Alice', email: 'alice@example.com', role: 'admin', createdAt: new Date() },
{ id: '2', name: 'Bob', email: 'bob@example.com', role: 'user', createdAt: new Date() },
]
// ID와 이름만 추출
const userSummaries = users.map(propsExtractor('id', 'name'))
// => [{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }]
// 중첩된 map에서도 간결하게 작성 가능
const departments = [
{ name: 'Engineering', members: users },
{ name: 'Sales', members: users },
]
const summaries = departments.map(dept => ({
department: dept.name,
members: dept.members.map(propsExtractor('id', 'name'))
}))

동작 원리

  1. propsExtractor는 가변 인자로 추출할 프로퍼티 이름을 받습니다
  2. 클로저로 (obj: Props) => Pick<Props, PropKey> 타입의 함수를 반환합니다
  3. 반환된 함수는 Object.hasOwn으로 프로퍼티 존재를 확인한 후 추출합니다
  4. TypeScript의 Pick 유틸리티 타입으로 반환값의 타입을 정확하게 추론합니다

Object.hasOwn을 사용하여 프로토타입 체인의 프로퍼티를 잘못 추출하지 않도록 안전성을 확보합니다.

장점

  • 가독성이 높음: map(propsExtractor('id', 'name'))처럼 의도가 명확합니다
  • 타입 안전: TypeScript 타입 추론으로 추출 후 타입이 정확하게 결정됩니다
  • 재사용 가능: 한 번 정의하면 여러 곳에서 재사용할 수 있습니다
  • 중첩에 강함: mapBy의 다중 적용에서도 가독성을 유지합니다

주의사항

프로퍼티가 존재하지 않으면 결과에 포함되지 않습니다 (undefined도 아님). 모든 프로퍼티를 포함하려면 Object.hasOwn 검사를 제거해야 합니다. 또한 추출 대상 프로퍼티가 많은 경우 명시적으로 인터페이스를 정의하는 것이 유지보수에 더 좋을 수 있습니다.

응용

  • API 응답에서 필요한 필드만 추출하여 클라이언트에 반환
  • 로그 출력 시 민감한 정보를 포함하는 프로퍼티 제외 (역필터 버전 생성)
  • Redux 또는 Zustand 셀렉터에서 부분 상태 추출
  • GraphQL 필드 선택과 유사한 부분 검색 로직 구현