Typescript

[TypeScript] Component Polymorphic하게 사용하기

차노도리 2024. 1. 27. 18:08

잘못된  Polymorphic Component 예시

  • component 타입에 따라 필요한 props 다름.
  • 모든 props 선택적(optional)으로 처리되어, 런타임에 필요한 props 누락될  있음

 

ex)

import React, { MouseEventHandler } from "react";

type ButtonType = "button" | "a";

interface ButtonProps {
  component: ButtonType;
  href?: string;
  onclick?: MouseEventHandler<HTMLAnchorElement & HTMLButtonElement>;
  children: React.ReactNode;
}

const Button = ({ component, href, onclick, children }: ButtonProps) => {
  return component === "a" ? (
    <a href={href}>{children}</a>
  ) : (
    <button onClick={onclick}>{children}</button>
  );
};

export default Button;

 

 

개선된 Polymorphic Component 예시

  • 제네릭 타입을 사용하여 컴포넌트의 타입을 명확하게 정의
  • component 타입에 맞는 적절한 props 전달할 있도록 강제
  •  props 사용으로 인한 런타임 오류의 가능성을 줄일 수 있음

 

ex)

type ButtonType = "button" | "a";

type PolymorphicComponentProps<
  T extends ButtonType,
  PropsType = Record<string, unknown>
> = {
  component?: T;
} & PropsType &
  React.ComponentPropsWithoutRef<T> & {
    ref?: React.ComponentPropsWithRef<T>["ref"];
  };

interface ButtonProps {
  children: React.ReactNode;
}

const PolymorphicButton = <T extends ButtonType = "button">({
  component,
  children,
  ...props
}: PolymorphicComponentProps<T, ButtonProps>) => {
  const Component = (component ?? "button") as React.ElementType;

  return (
    <Component className="button" {...props}>
      {children}
    </Component>
  );
};

export default PolymorphicButton;

 

 

정리

  • 잘못된 polymorphic 컴포넌트 사용 시, component 타입에 따라 필요한 props가 명확하지 않아 오류가 발생할 수 있음
  • 개선된 접근 방식을 통해, component 타입에 맞는 적절한 props 강제함으로써 타입 안전성을 향상시킬  있음