🤔
入力フォームのコンポーネントを作ってOmitを理解する
Omitってなんだ?
- OmitはTypescriptにあるユーティリティ型(型を操作するための型)
- Omitは型から任意のプロパティを除外できる
使い方
type Sample = Omit<任意の型, '除外したいプロパティ名'>
実際に使ってみた
まず、Omitをどんな時に使ったかなんですが、下のフォームをコンポーネント化する時に使いました。RHFとShadcnUIを組み合わせてFormを作ると下のようなコードになると思うんですけどこれ4つとかになるとめっちゃだるくない?って感じました。
BeforeInputForm.tsx
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>名前</FormLabel>
<FormControl>
<Input placeholder="山田 太郎" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>メールアドレス</FormLabel>
<FormControl>
<Input placeholder="example@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">送信</Button>
</form>
</Form>
で、上のコードをコンポーネント化したものがこの下のコードです。
InputFormComponent.tsx
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import type { FieldValues } from 'react-hook-form'
import type { InputFormProps } from '../../-types/inputform'
export const InputForm = <T extends FieldValues>({
name,
control,
label,
...inputProps
}: InputFormProps<T>) => {
return (
<FormField
control={control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<FormControl>
<Input
{...inputProps}
onChange={field.onChange}
value={field.value}
onBlur={field.onBlur}
disabled={field.disabled}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)
}
ここで使用しているInputFormPropsの型定義をするときにOmitを使用しました。
型定義は以下のコードで、Omitの部分を見るとHTMLInputElementのnameプロパティを除外しています。なぜ、除外しているか?
それは、RHFからimportしているUseControllerPropsとnameプロパティが重複してしまっているので、型エラーが起きていました。
なので、RHFのnameプロパティを優先するためにOmitを使用して除外しました。
inputform.d.ts
import { FieldValues, UseControllerProps } from "react-hook-form";
import { InputHTMLAttributes } from "react";
// 入力フォームの型定義
export interface InputFormProps<T extends FieldValues>
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'name'>,
UseControllerProps<T> {
label: string
}
まとめ
こんな感じでこの型と型のプロパティ、オプショナルじゃないのになんか重複してる!?って時に使えばいいんだなってことが分かりました。
Discussion