LoginSignup
28
7

More than 1 year has passed since last update.

TypeScriptの「こういう時ってどう書くの?」〜React Component編〜

Posted at

関数コンポーネントに型を付けたい!

React.VFC

React.VFCは引数にPropsのオブジェクトを受け取り、関数コンポーネントの型を作ります。

import React, { VFC } from 'react';

type Props = {
  propsA: string;
  propsB: number
};

export const Component: VFC<Props> = (props) => {
  return (
    // ...
  );
};

似たような型に、React.FCがありますが、暗黙的にchildrenが含まれてしまいます。
今後、React.FCからchildrenが抹消されると言われているため、なるべくReact.VFCを使って書き、
childrenが削除されてReact.VFCが非推奨になった時にReact.FCに置き換えましょう。

() => JSX.Element

React.VFCを使わずとも、愚直に1つずつ型を書く方法もあります。
関数コンポーネントはJSX.Elementを返すため、あとはPropsに型をつけてあげるだけです。

import React, { VFC } from 'react';

type Props = {
  propsA: string;
  propsB: number
};

export const Component = ({propsA, propsB}: Props): JSX.Element => {
  return (
    // ...
  );
};

ちなみに私は上のように書いたことはないですが、
React.VFC非推奨問題の対策として使っている人もいるみたいです。

コンポーネントのPropsの型を使いたい!

React.ComponentProps

React.ComponentPropsを使うことで、定義したComponentのProps部分のみの型を抽出することができます。

type CardProps = ComponentProps<typeof Card>;

refが含まれるかを明示的にしたい場合は、ComponentPropsではなく
ComponentPropsWithoutRef/ComponentPropsWithRefを使うと良さそうです。

〇〇要素の属性を全部Propsで渡せるように型定義したい!

JSX.IntrinsicElements['html要素名']

リンクのComponentで「aタグの全ての属性をPropsで渡せるようにしたい」というケースがあるかもしれません。
そのような時は、JSX.IntrinsicElements['html要素名']を使うと良いです。

import React, { VFC } from 'react';

type Props = JSX.IntrinsicElements['a'];

export Link: VFC<Props> = ({...attrs}) => {
  return (
    <a {...attrs}>リンク</a>
  );
};

childrenJSX を Propsで渡したい!

React.ReactNode / React.ReactChild / React.ReactElement

import React, { VFC, ReactNode } from 'react';

type Props = {
  children: ReactNode;
};

使い分け

基本 React.ReactNodeを使えば良いです。
より厳格に「string型は許容したくない!」「React.fragmentもだめ!」というケースのみ、
React.ReactChildReact.ReactElementを使いましょう。

▼ 参考

28
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
7