[TS] 스타일링 컴포넌트의 타입 정의(with styled-components)

hyeondoonge·2022년 4월 7일
0

🤦🏻‍♀️ 문제 인식

typescript + styled-components 조합을 사용하면서 컴포넌트 속성을 정의해야했다.

Chip, StyledChip 각각 두 속성을 정의했다.

export interface ChipProps {
  label: string;
  selected: boolean;
  onClick: (e: React.MouseEvent<HTMLInputElement>) => void;
}

export interface StyledChipProps {
  selected: boolean;
}

중복하는 속성이 있으면서도 연관이 있는 타입들인데 꼭 따로 정의해야하나라는 생각이 들었다.

타입을 하나만 정의하고 selected 속성만 선택적으로 사용하는 방법은 없을까를 고민하게 됐다.

아래 방법들을 통해 고민한 문제를 개선할 수 있었고, 그 중 가장 나은 방법이 typescript의 유틸리티 타입인 Pick였다.

1. 옵셔널 파라미터

export interface ChipProps {
  label?: string;
  selected: boolean;
  onClick: (e: React.MouseEvent<HTMLInputElement>) => void;
}

const StyledChip = styled.div<ChipProps>`
	//...
`;

export default function Chip({ label, selected, onClick }: ChipProps) {
  return (
    <StyledChip selected={selected} onClick={onClick}>
      {label}
    </StyledChip>
  );
}

label이 StyledChip을 위해서 옵셔널 해졌는데, 이런 변경점으로 Chip의 label 까지도 옵셔널 하게 됐다.
이 말은 Chip에 label값이 전달되지 않을 수도 있다는 거고, Chip 컴포넌트 제작자와의 의도(클릭가능하며 라벨이 있는 chip)와는 다르게 된다.

이를 해치지 않으면서 ChipProps에서 필요한 속성만 사용할 수 있는 방법은 없을까?

2. 리터럴 속성

const StyledChip = styled.div<{ selected: boolean }>`
	// ...
`;

스타일링에 사용될 속성들을 리터럴로 정의한다.
간단한 방법이지만, 이는 ChipProps와 일관성을 유지해야하기 때문에 각각의 속성변경이 서로에게 영향을 줄 수 있다.

3. Pick, Omit

타입을 변환하기 위해 사용할 수 있는 유틸리티 타입을 제공하고 있다.
Pick과 Omit은 특정 Type에서 Key의 집합을 선택/제거해 타입을 생성하는 것을 도와준다.

const StyledChip = styled.div<Pick<ChipProps, 'selected'>>`
	// ...
`;

조금 길긴 하지만, ChipProps Type을 일부 사용하는 거기 때문에 내부 타입들을 공유할 수 있다.
위의 문제가 개선됐다.

const StyledChip = styled.div<Omit<ChipProps, 'label, onClick'>>`
	// ...
`;

Omit타입의 사용은 Pick타입과 비교해 코드를 읽기가 어려울 수 있다.
속성이 들어갈 위치에는 스타일링에 사용되는 속성이 들어가는 것이 더 용이할 것 같다.


이후 새로운 방법을 알게되면 계속 기록해나가야야겠다...

0개의 댓글

관련 채용 정보