4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【TypeScript】 有効な状態を表す値だけを許可する

Last updated at Posted at 2021-12-21

はじめに

この記事は、JSL(日本システム技研) Advent Calendar 2021 の記事です。

  • 環境
    • TypeScript v4.5.3

伝えたいこと

  • 有効と無効、両方の状態を表現するタイプはエラーの元なので、注意が必要です。

大型旅客機エアバスA100が墜落、多くの犠牲者が…。

  • 飛行機の設計に携わるエンジニアの話。

A先輩 「B君。エアバスA100の操縦システムの設計よろしく。」

     「操縦士用と副操縦士用の操縦桿が2つあって独立しているから、どっちも機能するようにしておいて。」

B君 「はい、わかりました!! 任せてください!! 」

    (…とは言ったもののどうやって作るんだろ。)

interface CockpitControls {
  /** 操縦桿の角度 0 = ニュートラル */ 
  leftSideStick: number;
  rightSideStick: number;
}

B君 ( まず右の操縦桿と左の操縦桿をモデル化させます、と。)

    ( 操縦桿を手前に引いたら:airplane: の高度があがって、操縦桿を奥に押すと:airplane: の高度が下がるんですよね。多分。)

function getStickSetting(controls: CockpitControls) { 
  return controls.leftSideStick;
}

B君 (操縦桿の状態を出力する関数はこんな感じか? とりあえず、これでいいか。)

    (…あ、でも、これだと右の操縦桿が機能していないな。)


function getStickSetting(controls: CockpitControls) { 
  const {leftSideStick, rightSideStick} = controls; 
  if (leftSideStick === 0) {
    return rightSideStick; 
  }
  return leftSideStick; }

B君 「よし。これで。ok」

    (…と思ったけど、左が0だった場合のみ右が機能するってことしか確証できないんじゃないかな…。)
    (じゃあ一応、右が0の場合も考慮しておこう…。)

function getStickSetting(controls: CockpitControls) { 
  const {leftSideStick, rightSideStick} = controls; 
  if (leftSideStick === 0) {
    return rightSideStick;
  } else if (rightSideStick === 0) {
    return leftSideStick; 
  }
}

B君 「よし。これでどっちの操縦桿も機能するだろう。」
  「A先輩、実装しました。レビューお願いします。」

A先輩 「おー。お疲れ様ー。」
   「ok、確認するね。…ね、これ、もし操縦桿が両方ともニュートラルじゃなかったら、どうするの?」

B君 「…あ、なるほど。すみません。修正します。」

   (もし両方とも、0じゃなかったら、どっちの操縦桿を有効にすればいいんだろう…。)

  「…わかった:bulb: 右と左の操縦桿の数値を足して平均値を出そう! 」

function getStickSetting(controls: CockpitControls) { 
  const {leftSideStick, rightSideStick} = controls; 
  if (leftSideStick === 0) {
    return rightSideStick;
  } else if (rightSideStick === 0) {
    return leftSideStick; 
  }
  return (controls.leftSideStick + controls.rightSideStick) / 2

ある日のニュース

アナウンサー 「リオデジャネイロ発エアバスA100がセントポール群島付近の大西洋上に墜落しました。」

      「事故の影響で、多くの犠牲者が出てている模様です。」

      「それでは墜落直近のコックピットのレコーダーの音声をお聞きください。」

レコーダーに録音された音声

操縦士 「 おい! 落ちるぞ!!」

    「墜落しないように、高度を下げてスピードを出すんだ!! 」

    「こっちと同じように、そっちの操縦桿も操作しろ!! 」

副操縦士 「はい!! わかりました!! 」

操縦士 「 スピードが下がっているぞ!! スピードを上げるんだ!! 」

副操縦士「 はい!! さっきからやっています!! でも何故かスピードが下がっています!! 」

操縦士 「お、お前、何をしている!!?? 」

副操縦士 「さっきからずっと操縦桿を引いています!! 」

操縦士 「おい! 操縦桿を引いてどうする?! 」
    「機首を上げるな!! 操縦桿を押してスピードを上げろ! 」
    「落ちるぞお-!! 」:airplane: :arrow_lower_right: :fire:

次のレビュー会にて

A先輩 「 飛行機落ちちゃったらしいじゃん。 」
     「右の操縦桿は手前に引いて、左の操縦桿は奥に押して、操作指示が相殺されたんだってね。」

B君 「はい。すみません。みたいですね…。」

A先輩 「そもそもgetStickSetting()は必要ないんじゃないかな?」
   「関数で、左が0だったら○○とか、右が0だったら××とか。ごちゃごちゃ考えないでさ。型定義の時に単純にこうすればよかったんじゃない?」

interface CockpitControls {
  stickAngle: number;
}

B君 「…あ。なるほどです。」

まとめ

  • 型を設定する時は有効な状態を表す値だけを許可するようにしてください。
  • コードは書きやすくなり、チェックも楽になります。

参考文献

4
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?