O hirunewani blog

ReactとTypeScriptでHTML属性を拡張する方法について

Created at

ReactとTypeScriptでHTML属性を拡張する方法について書いた。React.ComponentPropsWithoutRefやReact.ComponentPropsWithRef、React.ComponentProps、JSX.IntrinsicElements、React.DetailedHTMLProps、React.ButtonHTMLAttributes、React.HTMLProps、React.AllHTMLAttributes、React.HTMLAttributesなど。

HTML要素の属性は、歴史的な理由などにより様々な記述ができる。

  1. React.ComponentPropsWithoutRef<“button”>
    1. 基本的にこれだけ覚えておけばいい。
    2. React.ComponentPropsに依存。
  2. React.ComponentPropsWithRef<“button”>
    1. React.ComponentPropsに依存。
    2. Ref Forwarding対応をする場合に使用。
    3. Ref Forwardingより単純にRefを渡す方が基本的に有益なため、あまり使う機会はないかもしれない。
  3. React.ComponentProps<”button”>
    1. Forwarded Refかの判別が困難なため、React.ComponentPropsWithoutRefとReact.ComponentPropsWithRefが推奨されている。
    2. JSX.IntrinsicElementsに依存。
  4. JSX.IntrinsicElements[“button”]
    1. React.DetailedHTMLPropsに依存
  5. React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
    1. 対応したReact.XXHTMLAttributesに依存
  6. React.ButtonHTMLAttributes<HTMLButtonElement>
    1. 各属性がベタ書きされている。本質。
  7. React.HTMLProps<HTMLButtonElement>
    1. React.AllHTMLAttributesに依存
    2. Isomorphic componentsを雑に作りたい場合など、とりあえずで型を与えたい場合に便利かもしれない…
  8. React.AllHTMLAttributes<HTMLButtonElement>
    1. React.HTMLAttributesに依存
    2. その名の通り全ての属性が与えられる。
    3. 要素によって規約が異なる属性値は丸められている。
      1. 例えばtypeがstringになる。
  9. React.HTMLAttributes<HTMLButtonElement>
    1. Aria属性やハンドラーなど、共通して与えられる標準的なHTML属性が定義されている。
    2. その要素固有の属性が与えられない。

React.ComponentPropsWithoutRefを利用したコンポーネントの例。

interface SomeComponentProps extends React.ComponentPropsWithoutRef<"button"> {
  additionalProp?: string;
}

export const SomeComponent = (props: SomeComponentProps) => {
  return <button type={props.type}>SomeComponent</button>;
};