typescript や javascript で format っぽいことをするには

javascript には、java や C# などにある format の様に書式化するものがありません。
数値や文字列、日付の書式化に対応するのは辛いですが、文字列に変数を展開するものであれば比較的簡単なので作ってみます。

format っぽいことをする関数

javascript なら、

function fmt(template, values) {
  return !values
  ? template
  : new Function(...Object.keys(values), `return \`${template}\`;`)(...Object.values(values).map(value => value ?? ''));
}

typescript なら型の定義を追加して、

function fmt(template: string, values?: { [key: string]: string | number | null | undefined }): string {
  return !values
  ? template
  : new Function(...Object.keys(values), `return \`${template}\`;`)(...Object.values(values).map(value => value ?? ''));
}

という関数で実現できます。

使い方

1つ目の引数 template に、テンプレートリテラルのような文字列
2つ目の引数 values に、展開する値をプロパティに持つオブジェクト
を指定します。
戻り値に展開後の文字列が返されます。

以下のように使います。

fmt('${name}による${codeTitle}メモ。${name}は${morning}時起床。${night}時就寝。',
  {
    name: '熊右衛門',
    codeTitle: 'フォーマットの',
    morning: 5,
    night: 21
  });

// 返される文字列
"熊右衛門によるフォーマットのメモ。熊右衛門は5時起床。21時就寝。"

解説

色付した部分を解説して行きます。
理解のしやすさを優先しますので、実際に Object.keys と Object.values が返してくる順が違う可能性がありますが、対ではあるので問題ありません。

  return !values
  ? template
  : new Function(...Object.keys(values), `return \`${template}\`;`)(...Object.values(values).map(value => value ?? ''));

values が undefined なら template をそのまま返します。
values を必須にするなら不要な判定です。

  return !values
  ? template
  : new Function(...Object.keys(values), `return \`${template}\`;`)(...Object.values(values).map(value => value ?? ''));

ファンクションのコンストラクタに、例にした引数を与えた場合は以下のように展開されるイメージです。

new Function('name', 'codeTitle', 'morning', 'night',
  'return `${name}による${codeTitle}メモ。${name}は${morning}時起床。${night}時就寝。`;')

コードに展開されるので、template と values に与える値に注意しましょう。
以下のような関数が作られます。関数名は仮に kuma としました。

function kuma(name, codeTitle, morning, night) {
  return `${name}による${codeTitle}メモ。${name}は${morning}時起床。${night}時就寝。`;
}
  return !values
  ? template
  : new Function(...Object.keys(values), `return \`${template}\`;`)(...Object.values(values).map(value => value ?? ''));

オブジェクトが持つ値を並べます。
null や undefined は空文字にしています。

('熊右衛門', 'フォーマットの', 5, 21)

と展開されるイメージです。
なので、

kuma('熊右衛門', 'フォーマットの', 5, 21)

という形になり、展開された文字列を戻り値として得られます。

プロを目指す人のためのTypeScript入門 (Amazon)

コメント