FUNCTIONAL UTILITIES

함수형 유틸 타입 보존

map/filter/reduce를 나열하는 것보다 입력 타입, 콜백 반환 타입, 좁혀진 타입이 파이프라인 끝까지 유지되는지가 TypeScript의 핵심이다.

01

입력 모델

User[]처럼 원본 배열과 nullable 필드를 명확히 둔다.

readonly 여부도 결정
02

filter/narrow

isActiveUser 같은 type guard를 쓰면 뒤 단계에서 User 타입이 좁혀진다.

boolean 함수와 차이
03

map/project

필요한 필드만 뽑아 ViewModel로 변환하고 반환 타입을 추론시킨다.

T → U
04

reduce/fold

초기값 타입을 명시해 accumulator가 any로 퍼지지 않게 한다.

empty array 대비
pipe
앞 함수 출력이 다음 입력과 일치해야 함 제네릭 pipe는 오버로드나 variadic tuple로 단계별 타입을 이어야 한다.
중간 any 금지
curry
인자를 나눠도 남은 인자 타입 유지 부분 적용 뒤 반환 함수가 어떤 인자를 기다리는지 드러나야 한다.
placeholder는 복잡도 증가
filter(Boolean)
값은 줄지만 타입이 충분히 좁혀지지 않을 수 있음 nonNullable type guard를 별도로 두면 T에서 null/undefined가 제거된다.
as 남발 방지
library fp
lodash/fp, Ramda의 curry 순서 확인 data-first/data-last 차이가 추론과 읽기 방향을 바꾼다.
팀 규칙 필요

도입 전 기준

읽기 방향 pipe를 쓰면 데이터 흐름이 왼쪽에서 오른쪽으로 읽혀야 한다.
타입 손실 파이프라인 중간에 any나 unknown이 생기면 직접 함수가 더 낫다.
디버깅 지점 중간 값을 로깅하거나 테스트할 수 있도록 작은 순수 함수로 쪼갠다.