본문 바로가기

FrontEnd

리액트 패턴 : 타입스크립트를 활용해 as Props 사용하기

반응형

원문 보기

 

React polymorphic components with TypeScript

Polymorphic components is a powerful React pattern for controlling how your components render in DOM.

isamatov.com

A polymorphic component is a popular React pattern.

폴리모픽 컴포넌트 패턴은 매우 유명한 리액트 패턴 중 하나입니다. 컴포넌트를 as를 사용하여 button을 a, div로 사용할 수 있게 해줍니다.

TypeScript와 제네릭을 사용하여 강력한 타입 체킹이 더해진 다형적 컴포넌트를 작성하는 방법을 살펴보겠습니다.

 

Overview of polymorphic components (폴리모픽 컴포넌트 개요)

API가 어떻게 사용되는지를 확인합니다. 버튼이 a 태그처럼 사용되고 있네요?

버튼이 아니라 a 태그입니다.

즉 버튼은 a와 동일한 props를 허용해야 합니다.

Simple implementation (간단한 구현)

타입체킹 없는 기본 구현 방법입니다.

애니스크립트 두둥

문제는 클라이언트가 잘못된 props를 전달하는 것을 방지하는 메커니즘이 없다는 것입니다.

??

타입스크립트로 타입 체크하기

다음 단계는 컴포넌트로 전달되는 props의 타입 검사를 강화하는 것입니다.

위의 코드는 제네릭을 도입합니다. 컴포넌트를 일반적으로 만들었습니다.
const Button = <T extends ElementType = "button">

 

ElementType은 React의 유틸리티 타입입니다.
버튼이 HTML 태그 및 기타 React 컴포넌트 타입만 허용하도록 제네릭 매개변수 T를 ElementType으로 설정합니다.
우리가 직접 정의한 props를 저장하는 MyButtonProps 타입에 T를 전달합니다.
MyButtonProps 내에서 as prop의 타입을 T로 설정합니다.
 
Button Props의 최종 타입은 MyButtonProps<T> & ComponentPropsWithoutRef<T>입니다.
이 타입은 직접 정의한 props와 ComponentPropsWithoutRef의 intersection 타입입니다.
ComponentPropsWithoutRef는 React 컴포넌트에 대한 기본 props 세트를 포함하는 React 라이브러리의 타입입니다.
 
이제 Button 컴포넌트는 as 값을 기반으로 수락하는 소품을 동적으로 계산할 수 있습니다.

이전의 href는 오류 발생!

오류 메시지는 복잡합니다만, 중요한 부분은 'IntrinsicAttributes & MyButtonProps<"button"> 타입에 'href' 애트리뷰트가 존재하지 않는다는 것입니다.
as를 "a"로  전달하면 오류가 사라집니다.

마지막 한 단계가 남아있습니다.

 

우리 컴포넌트의 props와 ComponentPropsWithoutRef에서 제공하는 리액트 기본 props 간에 이름 충돌이 없는지 확인하고 싶습니다.

이름 충돌이 있으면 혼란스러운 TypeScript 경고가 발생할 수 있습니다.

오류를 수정하는 것은 간단합니다. Omit을 사용하여 리액트 기본 컴포넌트들의 props에서 우리 컴포넌트의 props 이름을 생략해줍니다.

최종 결과

 

Omit은 ComponentPropsWithoutRef에서 MyButtonProps의 모든 소품 키를 제외하여 새 타입을 구성하는 TypeScript 유틸리티입니다.
생략을 사용하여 두 타입 간의 이름 충돌 충돌을 방지했습니다.
 



 

 

 

반응형