원글: ts-pattern은 더 멋진 if문이 아니다
https://toss.tech/article/ts-pattern-usage
ts-pattern은 조건부 분기문에서 타입을 관리하는 걸 용이하게 해주는 도구다. 다만 이 글에서 ts-pattern의 실사용이나 벤치마크 결과가 인상적인 건 아님. 댓글까지 보면, benny라는 유지보수도 잘 안되는 벤치마크 툴 써서 했다고 함.
글 내용보다는 타입 사용이나 간결한 코드 작성에 있어서 도움이 될 만한 패턴이 있어서 남긴다.
switch에서 satisfies 사용하기 #
Exhaustive matching은 ts의 switch문에서 유용하게 쓸 수 있다. 근데 안 쓰인 값이 없는지를 switch default문에서 satisfies never를 통해서 검증할 수 있다.
type Theme = "light" | "dark" | "system";
function getTheme(key: Theme) {
switch (key) {
case "light":
console.log("라이트 테마");
break;
case "dark":
console.log("다크 테마");
break;
case "system":
console.log("시스템 테마");
break;
default:
key satisfies never;
// 나올 수 없는 코드
}
}
위의 Theme 유니온 타입에 다른 걸 추가하면 default 케이스에서 satisfies never가 만족되지 않아서 타입 에러가 뜨는 걸 볼 수 있다.
IIFE 써서 컴포넌트 렌더링 #
분기 처리를 담당하는 컴포넌트나 render** 함수를 만드는 경우도 있다. 물론 react query의 loading 상태를 이용해 스켈레톤을 보여준다든가 하는 로직은 많이 반복되니까 컴포넌트로 빼도 좋겠다. 하지만 간단한 코드의 경우 IIFE로도 처리 가능
type Role = "user" | "assistant" | "admin";
interface BubbleProps {
role: Role;
content: string;
timestamp?: Date;
}
function Bubble({ role, content, timestamp }: BubbleProps) {
return (
<div className="bubble-container">
{/* 다른 코드들... */}
{(() => {
switch (role) {
case "admin":
return <AdminBubble content={content} timestamp={timestamp} />;
case "user":
return <UserBubble content={content} timestamp={timestamp} />;
case "assistant":
return <AssistantBubble content={content} timestamp={timestamp} />;
default:
role satisfies never; // 앞에서 본 패턴
return null;
}
})()}
</div>
);
}
물론 IIFE 내에서 if-else로 처리하는 것도 가능한데 나는 ts로 Exhaustive matching을 할 때 switch을 좋아해서 이렇게 한 것 뿐이다.
토스 내부에선 SwitchCase 컴포넌트도 따로 있어서 그걸 쓸 수도 있다고 한다.
ts-pattern 라이브러리: https://github.com/gvergnaud/ts-pattern