【TS初級から中級へ】ジェネリクスで処理をまとめてスッキリ
なかなか理解が難しいTypeScriptのジェネリクス。特にプログラミングを始めたての頃は、なんかよくわかんないし、何に使うのかいまいちイメージができません。
でも、ジェネリクスを使いこなせるとかっこいいですよね。初級から中級になった感じがします。
実際に使えるようになるとすごく便利でコードもスッキリします。
詳しい説明はサバイバルTypeScriptにゆずるとして、簡単に、どんなふうに使えるの?というのを紹介します。
似たような処理をまとめる
ジェネリクスのいいところは、似たような処理を1つにまとめてスッキリさせるところです。
並び替えの処理を例にしましょう。アプリのユーザーを特定の条件で並べ替えするとします。
ユーザーには種類があり、「一般ユーザー(NormalUser
)」と「特別なユーザー(SpecialUser
)」があったとします。
型にするとこんな感じです。
type NormalUser = {
id: number
name: string
createdAt: string
userType: "normal" | "special"
}
type SpecialUser = {
id: number
name: string
createdAt: string
userType: "normal" | "special"
job: string
followers: string[]
}
このユーザーを、id
、name
、createdAt
で並べ替えます。3つの方法を比べてみましょう。
(1)処理を2つ書く
単純に考えると、別々の処理を書きたくなってしまいます。なぜなら型が違うから。
const sortNormalUser = (users: NormalUser[]) => {
// id、name、createdAtでの並び替え処理
}
const sortSpecialUser = (users: SpecialUser[]) => {
// id、name、createdAtでの並び替え処理
}
しかし、これだとNormalUser
とSpecialUser
を混ぜて並び替えたい時は使えませんよね。
(2)ユニオン型を使う
次はユニオン型を使う方法です。
const sortUser = (users: (NormalUser | SpecialUser)[]) => {
// id、name、createdAtでの並び替え処理
}
うまく行きそうです。
が、新しいユーザー型(TemporalyUser
)が増えた場合はどうでしょう?
sortUser()
の引数の型に追加すれば良いだけですが、今後ユーザー型が増えるたびに追加するのは面倒です。
(3)ジェネリクスを使う
受け取る引数の型がなんであれ、並び替えに使うのはid
、name
、createdAt
の3つだけです。
この3つを持つ型ならなんでもOKにしたいですよね!
そこで使えるのがジェネリクスです。まずは並び替えに必要な情報だけを持った型SortableUser
を宣言します。
type SortableUser = {
id: number
name: string
createdAt: number
}
以下のsortUser()
では、SortableUser
をextendsした型ならなんでも受け入れます。つまり、id
、name
、createdAt
があるオブジェクトならなんでもこの関数につっこんで並び替えできるんです。
type SortableUser = {
id: number
name: string
createdAt: number
}
const sortUser = <T extends SortableUser>(users: T[]) => {
// id、name、createdAtでの並び替え処理
}
const users = [
{id: 1, name: "普通のユーザー", createdAt: 1, userType: "normal"},
{id: 2, name: "特別なユーザー", createdAt: 2, userType: "special", job: "programmer", followers: [1]},
{id: 3, name: "一時ユーザー", createdAt: 3, userType: "temp", expiredAt: 3}
]
const sorted = sortUser(users)
これなら既存のsortUser()
の修正は最低限に、柔軟な関数を実装できます!
まとめ
使えるようになるまではジェネリクスっていつ使うの?とか、ほんとに便利なの??と思っていました。が、使えるようになるとスマートなコードを書けるようになり、エンジニアとしてレベルが上がった感じもします。
一緒にスマートなコードを書けるよう精進していきましょう!
Discussion