4
3

【TypeScript】filterのコールバックを英文っぽくリファクタする

Posted at

はじめに

filterのコールバックって、条件が多くなってくると見づらいですよね
最近思いついたリファクタが、めちゃ初歩的で地味だけど
案外気に入ってるので記事にしてみます

Before

車の情報を持つinterfaceがあるとします

interface Car {
    name: string
    type: CarType
    color: BodyColor
}

enum CarType {
    VAN,
    SUV,
    COUPE,
}

enum BodyColor {
    BLACK,
    WHITE,
    RED
}

Carの配列があるとします

const cars: Car[] = [
    {name: 'HIACE', type: CarType.VAN, color: BodyColor.BLACK},
    {name: 'LAND CRUISER', type: CarType.SUV, color: BodyColor.WHITE},
    {name: '86', type: CarType.COUPE, color: BodyColor.RED},
    {name: 'CARAVAN', type: CarType.VAN, color: BodyColor.RED},
    {name: 'HILUX SURF', type: CarType.SUV, color: BodyColor.BLACK},
    {name: 'SUPRA', type: CarType.COUPE, color: BodyColor.WHITE},
]

黒いSUVが大好きなので
CarTypeSUV、かつ BodyColorBlack
の条件でfilterしたいとします

const suvList1 = cars.filter(car => car.type === CarType.SUV && car.color === BodyColor.BLACK)

普通にfilterしたらこうですね

After

by というfilterのコールバックを作ります

const by = (type: CarType, color: BodyColor) => (car: Car) => {
    return car.type === type && car.color === color
}

filterの条件となる引数 type, color を受け取り、関数を返します。
返される関数はcarを受け取り、条件のbooleanを返します

byコールバックを使ってみるとこうなります

const suvList = cars.filter(by(CarType.SUV, BodyColor.BLACK))

Cars filter by SUV and BLACK

気持ち良いくらい英文的で綺麗なコードになりました

おわりに

めっちゃ地味だけど、結構好きなリファクタです

ただスコープ内に複数コールバック作りたい時は命名に困るので
declare globalでfilterByXXみたいな拡張関数作っても良いけど
お手軽にできるところはいいところですね

可読性にはとことんこだわりたい

4
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3