Apr 15, 2022
5 mins read
今回もmattさんのTypeScriptTipsをまとめていく。
TypeScript Tip #8
Reactのジェネリクスを使用して、動的で柔軟なコンポーネントを作成することができる。
以下のコードはReactのサンプルのコードである。
Table
コンポーネントのprops
に存在するitems
はオブジェクトの配列になっている。
オブジェクトはプロパティid
のみを保持している。
import React from 'react'
interface TableProps {
items: { id: string }[]
renderItem: (item: { id: string }) => React.ReactNode
}
export const Table = (props: TableProps) => {
return null
}
const Component = () => {
return (
<Table
items={[
{
id: '1',
}
]}
renderItem={(item) => <div>{ item.id }</div>}
></Table>
)
}
上記の場合、propsitems
にオブジェクトのid
以外のプロパティを定義したい場合、TableProps
にも追加をしてやる必要がある。
以下はそのサンプルコード
import React from 'react'
interface TableProps {
items: { id: string, name: string }[]
// 🔼プロパティnameを追加している
renderItem: (item: { id: string, name: string }) => React.ReactNode
// 🔼プロパティnameを追加している
}
export const Table = (props: TableProps) => {
return null
}
const Component = () => {
return (
<Table
items={[
{
id: '1',
name: 'issei'
// 🔼propsにnameを追加している
}
]}
renderItem={(item) => <div>{ item.id }</div>}
></Table>
)
}
プロパティを追加する度に型定義を追加してやる必要があるため、これをジェネリクスを利用して定義を動的に変更させる。 ジェネリクスを利用したサンプルコードは以下。
import React from 'react'
interface TableProps<TItem> {
items: TItem[]
renderItem: (item: TItem) => React.ReactNode
}
export function Table<TItem>(props: TableProps<TItem>) {
return null
}
const Component = () => {
return (
<Table
items={[
{
id: '1',
name: 'Matt'
}
]}
renderItem={(item) => <div>{ item.id }</div>}
></Table>
)
}
TableProps
の型定義でジェネリクスを定義している。interface TableProps<TItem> {
items: TItem[]
renderItem: (item: TItem) => React.ReactNode
}
export function Table<TItem>(props: TableProps<TItem>) {
return null
}
// or
const Table = <TItem extends unknown>(props: TableProps<TItem>) => {
return null;
};
const Component = () => {
return (
<Table
items={[
{
id: '1',
name: 'Matt'
// 🔼nameを追加しても動的に型推論することができる
}
]}
renderItem={(item) => <div>{ item.id }</div>}
></Table>
// 型定義内容
// function Table<{
// id: string;
// name: string;
// }>(props: TableProps<{
// id: string;
// name: string;
// }>): null
// )
}
かなり汎用性が高くなるため、使用することがあれば使用していきたい