(息抜きコーディング)if 文をごにょごにょ

ts-pattern 便利そう

こちらの記事を読んで

qiita.com

へー。ts-pattern ってライブラリがあるんだー便利そう

github.com

と思った

興味ある

んで、ts-pattern も興味はあるんだけど、それとは別でちょっと興味があったのが、例として書いてあるコード:

  const gameName = (() => {
    if (game.genre === 'rpg') {
      if (game.company === 'enix') {
        return 'dq1';
      } else if (game.company === 'nintendo') {
        return 'pokemon';
      }
      return 'ff1';
    } else if (game.genre === 'simulation') {
      if (game.company === 'maxis') {
        return 'simcity';
      }
      return '';
    }
    return '';
  })();

「これだと読みにくいから ts-pattern 使ったら分かりやすくなったよー!」ってお話なんだけど、↑の路線のままでも、もうちょっと読みやすくはできそうかなぁって思ったので遊んでみた。元記事に対しての反対意見ではなくて、ただコード例で遊んだだけのお話です!

その1:else をなくす

全部 return してるから else をなくしても大丈夫。↑のコードは好きじゃないけど、これなら自分はありかな

  const gameName = (() => {
    if (game.genre === 'rpg' && game.company === 'enix') {
      return 'dq1';
    }

    if (game.genre === 'rpg' && game.company === 'nintendo') {
      return 'pokemon';
    }

    if (game.genre === 'rpg') {
      return 'ff1';
    }

    if (game.genre === 'simulation' && game.company === 'maxis') {
      return 'simcity';
    }

    return '';
  })();

その2:game. をなくす

パラメータの分割代入を使ってちょっとすっきり

  const gameName = (({ genre, company }) => {
    if (genre === 'rpg' && company === 'enix') {
      return 'dq1';
    }

    if (genre === 'rpg' && company === 'nintendo') {
      return 'pokemon';
    }

    if (genre === 'rpg') {
      return 'ff1';
    }

    if (genre === 'simulation' && company === 'maxis') {
      return 'simcity';
    }

    return '';
  })(game);

その3:if を一行で書く

コーディングルールでだめな場合も多いとは思うけど

  const gameName = (({ genre, company }) => {
    if (genre === 'rpg' && company === 'enix') return 'dq1';
    if (genre === 'rpg' && company === 'nintendo') return 'pokemon';
    if (genre === 'rpg') return 'ff1';
    if (genre === 'simulation' && company === 'maxis') return 'simcity';
    return '';
  })(game);

ts-pattern を使った場合がこう↓だから、だいぶ近くなったかなー

  const gameName = match(game)
    .with({ genre: 'rpg', company: 'enix' }, () => 'dq1')
    .with({ genre: 'rpg', company: 'nintendo' }, () => 'pokemon')
    .with({ genre: 'rpg' }, () => 'ff1')
    .with({ genre: 'simulation', company: 'maxis' }, () => 'simcity')
    .otherwise(() => '');

それだけ!面白かった!

おまけ

コードを変えるのに簡単なテストを書いて使ったのだ

console.assert(getGameName({ genre: 'rpg', company: 'enix' }) === 'dq1')
console.assert(getGameName({ genre: 'rpg', company: 'nintendo' }) === 'pokemon')
console.assert(getGameName({ genre: 'rpg', company: 'square' }) === 'ff1')
console.assert(getGameName({ genre: 'rpg' }) === 'ff1')
console.assert(getGameName({ genre: 'simulation', company: 'maxis' }) === 'simcity')
console.assert(getGameName({ genre: 'simulation', company: 'other' }) === '')
console.assert(getGameName({ genre: 'other', company: 'enix' }) === '')