부모로부터 어떤 prop을 전달받아 호출하는 지에 따라 여러가지 모양이나 역할을 하는 컴포넌트를 렌더링할 수 있다.
그렇기때문에 재사용하는 공통 컴포넌트의 경우, 필요한 prop을 누락하지 않도록 해야한다.
그런데 이걸 가능하게 해주는 유틸리티 타입이 있다. !!!
ComponentPropsWithoutRef<T>
extends를 통해 상속하면 타입변수 T (예시에서는 "button")가 갖고있는 모든 프로퍼티를 prop으로 받을 수 있다.
적용 전
import { ReactNode } from "react";
import { buttonStyle } from "./style.css";
interface ButtonProps {
children: React.ReactNode;
variant: "primary" | "secondary" | "outline" | "accent";
icon?: ReactNode;
type?: "button" | "submit" | "reset"; // button 요소에서 사용하는 기본 type 속성
className?: string; // 추가적인 className을 지원하도록
onClick?: React.MouseEventHandler<HTMLButtonElement>; // 클릭 이벤트 핸들러
disabled?: boolean; // disabled 상태
// button 요소에서 다른 필요한 속성들 추가 가능
}
const ButtonComponent = ({ type = "button", ...args }: ButtonProps) => {
return (
<button
type={type}
className={`${buttonStyle[args.variant]} ${args.className}`}
{...args}
>
{args.icon}
{args.children}
</button>
);
};
export default ButtonComponent;
적용 후
import type { ComponentPropsWithoutRef, ReactNode } from "react";
import { buttonStyle } from "./style.css";
interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
children: React.ReactNode;
variant: "primary" | "secondary" | "outline" | "accent";
icon?: ReactNode;
}
const ButtonComponent = ({ type = "button", ...args }: ButtonProps) => {
return (
<button
type={type}
className={`${buttonStyle[args.variant]} ${args.className}`}
{...args}
>
{args.icon}
{args.children}
</button>
);
};
export default ButtonComponent;
비슷한 역할을 하는 HTMLAttributes<HTMLXXXElement> 도 있다
다만 HTML 요소에서 정의하는 기본 속성만을 받기때문에 icon과 같은 커스텀 prop은 포함되지 않는다
이 경우에는 명시적으로 추가해줘야 한다.
'개발 공부 일지 > TypeScript' 카테고리의 다른 글
[한입 챌린지] 타입 스크립트 챌린지 회고 (0) | 2025.03.09 |
---|---|
타입스크립트 - 제네릭 (0) | 2024.09.13 |
타입스크립트 - keyof, typeof (0) | 2024.09.11 |
타입스크립트 - Union, Intersection (0) | 2024.09.11 |
타입스크립트 - 리터럴 타입 / 타입 별칭 (0) | 2024.09.10 |