React.ComponentPropsを使うことで少しだけ便利にPropsの型を定義できます。
React.ComponentPropsで子コンポーネントのPropsの型を参照できます。
React.ComponentPropsを使わない
Todo.tsx
export type TodoProps = {
title: string;
isCompleted: boolean;
};
export const Todo = (props: TodoProps) => {
return (
<div>
<p>{props.title}</p>
<p>{props.isCompleted ? "完了" : "未完了"}</p>
</div>
);
};
TodoList.tsx
import type { TodoProps } from "src/pages/company/profile/Todo";
import { Todo } from "src/pages/company/profile/Todo";
type TodoListProps = {
todoList: TodoProps[];
};
export const TodoList = (props: TodoListProps) => {
return (
<div>
{props.todoList.map((todo) => {
return <Todo {...todo} />;
})}
</div>
);
};
TodoコンポーネントのPropsの型をexportして、TodoList側でimportして利用しています。
他にもTodoコンポーネントとTodoListコンポーネントの両方で同じ型の定義をする方法もあります。(コードなし)
React.ComponentPropsを活用
Todo.tsx
type TodoProps = {
title: string;
isCompleted: boolean;
};
export const Todo = (props: TodoProps) => {
return (
<div>
<p>{props.title}</p>
<p>{props.isCompleted ? "完了" : "未完了"}</p>
</div>
);
};
TodoList.tsx
import type { ComponentProps } from "react";
import { Todo } from "src/pages/company/profile/Todo";
type TodoListProps = {
todoList: ComponentProps<typeof Todo>[];
};
export const TodoList = (props: TodoListProps) => {
return (
<div>
{props.todoList.map((todo) => {
return <Todo {...todo} />;
})}
</div>
);
};
ComponentProps<typeof Todo>
がTodoPropsの代わりになっています。
ちょっと解説
ComponentProps<typeof Todo>
でTodoコンポーネントのPropsと同じ型を表しています。
ComponentProps<typeof Todo>[]
はTodoコンポーネントのPropsの型の配列を表しています。
ComponentProps<typeof Todo>["title"]
のように["〇〇"]
を繋げて、特定のプロパティの型を取得することもできます。
(ComponentProps<typeof Todo>["title"]
はTodoPropsのtitle
の型 = string型)
ComponentPropsを使うことで、
- 子コンポーネントの型をexport/importする必要がない。
- export/importしないから使う型を間違えることもない。(importがコンポーネントの指定1つになるから間違えない)
- 同じ型を複数書く必要もない。
みたいな恩恵を受けることができて、少し便利に型を書くことができました。