2
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.

if文やswitch文を用いた値の宣言でもconstで定義したい

Posted at

JavaScript、TypeScriptで値を扱うとき、letを用いて宣言を行うと可読性が著しく下がるので可能な限りconstを利用して宣言したいです。
この信条をもとに開発を行うと、宣言する値が分岐する場合でもconstで定義することになります。そのように作られたコードは以下のように可読性が下がります(この例は分岐の階層が1なのでまだマシで、階層が増えるとさらに見にくいコードになります)。

const colorSchema = (
  type === 'info'
    ? ({
        color: '#0288d1',
        backgroundColor: '#03a9f4',
      } as const)
    : type === 'success'
    ? ({
        color: '#2e7d32',
        backgroundColor: '#4caf50',
      } as const)
    : type === 'warning'
    ? ({
        color: '#ed6c02',
        backgroundColor: '#ff9800',
      } as const)
    : type === 'error'
    ? ({
        color: 'd32f2f',
        backgroundColor: '#ef5350',
      } as const)
    : ({
        color: 'inherit',
        backgroundColor: 'inherit',
      } as const)
) satisfies ColorSchema;

そのため、分岐が複雑な場合はその可読性の低下がletを使うことによる可読性の低下よりも大きいと考えられ、以下のようにletを使って宣言することが多いです。

let colorSchema: ColorSchema;

switch (type) {
  case 'info':
    colorSchema = {
      color: '#0288d1',
      backgroundColor: '#03a9f4',
    } as const;
    break;
  case 'success':
    colorSchema = {
      color: '#2e7d32',
      backgroundColor: '#4caf50',
    } as const;
    break;
  case 'warning':
    colorSchema = {
      color: '#ed6c02',
      backgroundColor: '#ff9800',
    } as const;
    break;
  case 'error':
    colorSchema = {
      color: 'd32f2f',
      backgroundColor: '#ef5350',
    } as const;
    break;
  default:
    colorSchema = {
      color: 'inherit',
      backgroundColor: 'inherit',
    } as const;
    break;
}

switch文による分岐になりましたので、どの分岐でどのような値が代入されているか分かりやすくなりました。この形式ではletを使っているので今後変更されるかもしれないことを頭の片隅に入れて読んでいく必要があります。
さらに、colorSchemaの型はこれだけ、実際に取りうるオブジェクトのユニオンではなくColorSchemaと推論されます。この例では対した問題にはなりませんが、オブジェクトが持つ値によって分岐を作るときに型を絞ること(制御フローによる型の絞り込み)が出来ないという面が劣っています。

これらを解決するのが分岐処理を関数で行わせてその結果を値として宣言するという方法です。

const colorSchema = (() => {
  switch (type) {
    case 'info':
      return {
        color: '#0288d1',
        backgroundColor: '#03a9f4',
      } as const;
    case 'success':
      return {
        color: '#2e7d32',
        backgroundColor: '#4caf50',
      } as const;
    case 'warning':
      return {
        color: '#ed6c02',
        backgroundColor: '#ff9800',
      } as const;
    case 'error':
      return {
        color: 'd32f2f',
        backgroundColor: '#ef5350',
      } as const;
    default:
      return {
        color: 'inherit',
        backgroundColor: 'inherit',
      } as const;
  }
})() satisfies { color: string; backgroundColor: string };

このようにすることで、分岐による可読性を保ったままconstで定義することが出来ます(型も詳細なオブジェクトのユニオンが得られます)。汎用的な分岐処理であれば都度無名関数で作成するのではなく、関数として宣言して使い回すようにしても良いと思います。

2
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
2
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?