ReactもしくはReactNativeをTypescriptで書いていると、コンポーネントに渡すPropsを定義することは日常茶飯事です。 そんな時、知っているとちょっと便利なTipsをご紹介します。
react
もしくはreact-native
のプロジェクトTypescript
を導入しているPartial
)がっつりコンポーネントの再利用を突き詰めていくと、割と細かい単位でコンポーネントを作成することになります。
個人的には、コンポーネントが細かくなればなるほどプロパティは必須のものが少なくなる印象です。
例えば、コンポーネントのスタイル等、親から指定したい場合とそうでない場合のもの等です。
そんな時、プロパティに?
を付けてオプション化していることはないでしょうか?
type CustomButtonProps = {
// ボタンの背景色
bgColor? : string
// ボタンの文字色
color? : string
// デバッグフラグ
isDebug? : boolean
}
全てのプロパティをオプションにしたい場合はPartial
が便利です。
下記の通り書いても、同じ結果が得られます。
type CustomButtonProps = Partial<{
bgColor: string
color: string
}>
|
)例えばstyle
のwidth
のように100
や"50%"
のように複数の型を受けたい場合に使用します。
type CustomViewProps = {
// stringもしくはnumberのいずれか
width : string | number
}
&
)union
と対の存在なのがintersection
です。
複数の型の両方の性質を持たせたい場合に利用します。
type Hoge = {
a : string
b : number
}
type Fuga = {
c : boolean;
d : string | number | boolean
}
// objはHogeとFugaの両方の性質(プロパティ)を持つ
const obj : Hoge & Fuga = {
a : '',
b : 0,
c : false,
d : ''
};
プリミティブ型の中でも特にこの値だけを受け付けたい、といった場合はリテラル型がオススメです。
例えば、先のunion
型と併用し、下記のように記載することでtype
は0
か1
か2
しか許さない型になります。
// Hogeのtypeは0か1か2のみ許可
type Hoge = {
type : 0 | 1 | 2
}
ちなみに先のPartial
で登場した?
を付けたオプションプロパティはデフォルトではundefined
です。
一見するとundefined
を複合させたunion
型なのでは?と思ってしまいます。
// 下記の2通りの書き方は同じ??
type Hoge = {
fuga? : string
}
type Puni = {
fuga : string | undefined
}
何が違うのかというと、?
の場合はfuga
プロパティが存在しないことを許容しています。
string | undefined
の場合、undefined
を渡さないとなりません。
type Hoge = {
fuga? : string
}
type Puni = {
fuga : string | undefined
}
// これはOK
const hoge : Hoge = {}
// Property 'fuga' is missing in type '{}' but required in type 'Puni'
const puni : Puni = {}
Pick
)Pick
で既存のtype
から特定のプロパティを抽出することができます。
既に作成したプロパティを部分的に使いまわしたい時に便利です。
// a,b,cの3つのプロパティを持つABC
type ABC = {
a : string
b : string
c : string
}
// ABCからa,bを持つABを作成
type AB = Pick<ABC , 'a' | 'b'>
ざっと紹介した限りでも、様々なProps
の定義パターンがあるように思えます。
個人的にはunion
やリテラルは使用頻度が高いと思うので、覚えておいて損はないと思います。