logo
Home
About
Works
Blog
Contact

TypeScriptのライブラリの型を拡張して、独自のpropsを渡せるコンポーネントを作る

2022-04-03

2022-04-03

4 min read

TypeScript

Chakra UI

目次


  1. 背景
  2. 課題
  3. 解決方法

背景

先日TypeScriptのライブラリの型を拡張して、独自のpropsを渡せるようにしたコンポーネントを作ろうとしたら、エラーが出て少しハマりました。

ライブラリで提供されているコンポーネントを少し拡張して、システム内で利用したい場合はよくあると思います。

今回は例としてTypeScriptChakra UIというCSS フレームワークの型に、独自propsを渡せるように拡張してみます。

ちなみにライブラリが提供する関数やコンポーネントは一度ラップして使用することで、ライブラリ事態に致命的な変更が起きた場合、修正を行いやすくなるという記事を以前どこかで見ました。今回は詳しく触れませんが、コンポーネントを拡張しない場合でも、独自コンポーネントとして定義したものを使用した方が管理しやすいかもしれませんね。

課題

まず独自のpropsを普通に渡して、コンポーネントを拡張してみます。

Chakra UIのBoxPropsを用いて、Boxコンポーネントに独自のpropsを渡せるようにしたTitleBoxという独自コンポーネントを作ってみます。

呼び出し元
function App() {
  return (
<TitleBox title='タイトル' hoverBgColor='red.100' bg='blue.100' />
); }
独自コンポーネント
type Props = BoxProps & {
  title: string;
  hoverBgColor: string;
}
const TitleBox:React.VFC<Props> = (props)=>{
  const {title, hoverBgColor} = props;
  return(
    <Box 
      {...props}
      _hover={{
        background: hoverBgColor
      }}
    >{title}</Box>
  )
}

TitleBoxコンポーネントのtitlehoverBgColorが独自のpropsになります。

このように独自のpropsを渡そうとした場合、下記のようなエラーが出ます。

どうやら元々のDOM要素に無いプロパティ(独自のprops)を渡そうとしているため、エラーが出てしまっているようです。

解決方法

下記のように、分割代入で独自に渡しているpropsを取り出し、残りをスプレット構文(...basePropsの部分)でまとめます。これで、basePropsには本来のBoxPropsのデータのみになります。これをBoxコンポーネントに渡せばエラーを解決できます。

独自コンポーネント修正後
type Props = BoxProps & {
  title: string;
  hoverBgColor: string;
}
const TitleBox:React.VFC<Props> = (props)=>{
const {title, hoverBgColor, ...baseProps} = props;
return(
<Box {...baseProps} _hover={{ background: hoverBgColor }} >{title}</Box>
) }