HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🌟
Programmers 최종 플젝 6조
/
[프론트] TWL
[프론트] TWL
/
Emotion CSS-in-JS Type declaration
Emotion CSS-in-JS Type declaration
Emotion CSS-in-JS Type declaration

Emotion CSS-in-JS Type declaration

생성일
Dec 4, 2021 10:50 AM
태그
TypeScript
Emotion
작성자
해결 완료
해결 완료

문제

다음과 같은 모달 버튼들을 모아놓은 컨테이너를 만들던 도중 고민이 생겼다.
모달 버튼에 isConfirm이라는 확인 버튼에 대한 여부를 boolean값으로 받는 버튼의 props를 생성해야 했는데, 기존 intrnisicAttributes에 없는 속성이라고 내뱉는 것.
이를 어떻게 해결해야 할까? 코드는 다음과 같다.
import styled from '@emotion/styled'; import React from 'react'; import styles from '@styles/index'; import { css } from '@emotion/react'; export interface ModalButtonsProps { modalType: string; width: string | number; onConfirm?: () => void; onClose: () => void; } const Button = styled.button` width: 80px; height: 32px; margin: 0 16px; font-size: ${styles.fontSize.small}; font-weight: 700; background: transparent; border: 0; border-radius: 16px; ${({ modalType }) => css` color: ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; border: 2px solid ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; `} ${({ modalType, onConfirm }: Partial<ModalButtonsProps>) => onConfirm && css` color: ${modalType === 'default' ? styles.colors.point : styles.colors.background}; background: ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; `}; `; const StyledModalButtons = styled.div` position: absolute; bottom: 30px; box-sizing: border-box; display: flex; justify-content: center; margin: 0 auto; `; const ModalButtons = ({ modalType = 'default', onClose, onConfirm, }: ModalButtonsProps) => { return ( <StyledModalButtons> {onConfirm && ( <Button modalType={modalType} onClick={onConfirm} isConfirm> 예 </Button> )} <Button modalType={modalType} onClick={onClose}> 아니오 </Button> </StyledModalButtons> ); }; export default ModalButtons;
 

해결

해당 이모션 공식 문서를 참조하면서 타입에 대해 좀 더 고민하기 시작했다.
여기서는, React.FC를 CSS-in-JS에 명시해주면 된다고 했다.
따라서 다음과 같이 수행하였다.
export interface ButtonProps { isConfirm: boolean; }
그러자,
'{ children: string; modalType: string; onClick: () => void; }' 형식은 'IntrinsicAttributes & ButtonProps & { children?: ReactNode; }' 형식에 할당할 수 없습니다. 'IntrinsicAttributes & ButtonProps & { children?: ReactNode; }' 형식에 'modalType' 속성이 없습니다.
라는 오류가 발생했다.
음... 아무래도 기존 ModalButtonProps에서 타입을 상속받아야 할 듯 싶다.

그런데 이상하다.

ModalButtonProps에서 ModalButtons를 상속한다?
사실 가장 추상성이 높은 건 Button인데 말이다.
자고로 인터페이스의 확장은 열려있지만, 수정은 닫혀있어야 한다.
그렇지만, 현재의 경우 onClick을 강제로 ModalButtonProps에 순수하게 넘겨줄 수 있는 방안이 없다.
따라서 다음과 같이 리팩토링하였다.
export interface ButtonProps { isConfirm?: boolean; modalType: string; onClick: () => void; } export interface ModalButtonsProps extends Partial<ButtonProps> { width: string | number; onConfirm: () => void; onClose: () => void; }
이제 가장 추상성 높은 ButtonProps를 상속 받음으로써 좀 더 유연한 구조가 되었다.
 
이후, 다음과 같이 수정한다.
${({ modalType }: ButtonProps) => css` color: ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; border: 2px solid ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; `} ${({ modalType, isConfirm }: ButtonProps) => isConfirm && css` color: ${modalType === 'default' ? styles.colors.point : styles.colors.background}; background: ${modalType === 'default' ? styles.colors.point : styles.colors.warning}; `};
 

결과

문제가 발견되지 않는다.
notion image
 
또한, 스토리북 역시 잘 동작한다!
notion image