본문 바로가기
C.W.K.
Stream
Lesson 05 of 07 · published

기본 타입 매개변수: 흔한 경우를 짧게 만들기

~7 min · generics, defaults, ergonomics

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"기본값은 선택지를 줄이지 않아. 대부분의 호출자가 같은 선택을 반복해서 적는 일을 없애."

함수 기본값과 닮은 문법

type Result<T, E = Error>에서 E의 기본값은 호출자가 두 번째 타입 인자를 생략했을 때 Error를 사용하겠다는 뜻이야. Result<User>Result<User, Error>와 같고, 특별한 오류가 필요하면 직접 바꿀 수 있어.

이 기능은 타입의 표현력을 늘리기보다 사용성을 다듬어. 흔한 경우는 짧게, 드문 경우는 여전히 정확하게 적게 해.

제약과 함께 쓸 수 있어

T extends Event = Event처럼 제약과 기본값을 함께 적을 수 있어. 기본값 자체도 제약을 만족해야 한다. 제약은 허용 범위를 정하고 기본값은 생략 시 선택을 정하므로 역할이 서로 달라.

추론이 기본값보다 먼저야

값 인자에서 타입을 추론할 수 있다면 컴파일러는 그 정보를 사용해. 기본값은 추론할 근거도, 명시한 타입 인자도 없을 때 들어간다. ‘기본값을 적었으니 항상 이 타입으로 시작한다’고 이해하면 호출 결과가 예상과 달라질 수 있어.

기본값이 너무 많으면 의도가 흐려져

모든 타입 매개변수에 기본값을 붙이면 호출은 짧아지지만 어떤 계약이 선택됐는지 감춰질 수 있어. 명백하고 안정적인 기본값에만 써. 도메인에서 반드시 결정해야 하는 선택은 호출자에게 남겨 두는 편이 낫다.

흔한 예로 Action<Payload = undefined>, Container<T = unknown>, Component<P = {}>처럼 자주 쓰는 자리에 기본 타입을 둘 수 있어. 기본값은 흔한 호출을 짧게 만들고 필요할 때만 명시적으로 덮어써.

대부분의 호출자가 같은 타입을 적는 자리만 기본값으로 만들고, 중요한 선택은 생략 가능하게 숨기지 마.

Code

Default 가 흔한 case 간결하게·typescript
// Default — 간결한 흔한 case.
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

function parse(s: string): Result<number> {  // E 가 Error 로 default
  const n = Number(s);
  if (Number.isNaN(n)) return { ok: false, error: new Error('NaN') };
  return { ok: true, value: n };
}

// 필요할 때 default override.
type CustomError = { code: number; msg: string };
function parseCustom(s: string): Result<number, CustomError> {
  // ...
  return { ok: false, error: { code: 1, msg: 'parse error' } };
}

// Constraint + default — library 패턴.
function event<T extends Event = Event>(handler: (e: T) => void) { /* ... */ }
event((e) => e.preventDefault());          // T = Event
event<MouseEvent>((e) => e.clientX);       // T = MouseEvent, narrow 됨

External links

Exercise

오류 타입 E의 기본값이 string인 ApiResponse<T, E = string>을 정의해. 성공 결과에는 ApiResponse<User>, 명시적인 오류 타입에는 ApiResponse<User, ValidationError>를 반환하는 함수를 각각 작성해 둘 다 타입 검사를 통과하는지 확인해.
Hint
두 번째 타입을 생략하면 기본 문자열이 사용돼. 제약도 함께 두면 호출자가 명시할 수 있는 타입의 범위를 제한할 수 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.