tips chips

日々の作業で出てきた技術メモの切れ端を置いておくページ

TypeScriptで動的な見出しレベルのReactコンポーネントを実現する

template literal stringのいい感じの使い方を発見した

level propsみたいなのに数値を渡してそれに応じて見出しレベルがh1, h2, h3… となるようなコンポーネントを作りたいときに

const Heading: React.FC<{level: 1 | 2 | 3, children: React.ReactNode}> = ({level, children}) => { const Wrapper = `h${level}` return <Wrapper>{children}</Wrapper> }

というようなコードを書くと、

TS2559: Type '{ children: ReactNode; }' has no properties in common with type 'IntrinsicAttributes'.

というような感じで怒られてしまう。

これはWrapperの型がstringと推論されてしまうために発生する。

この時、template literal typeを使って以下のように書くとスマートに書けて良さそう。

type Level = 2 | 3 | 4 const Heading: React.FC<{level: Level, children: React.ReactNode}> = ({level, children}) => { const Wrapper: `h${Level}` = `h${level}` return <Wrapper>{children}</Wrapper> }