フロントで電話番号をハイフン付きに変換する

##利用するライブラリについて
ユーザの入力した電話番号に対して、視認性を持たせるためハイフン区切りにしたい、もしくはハイフン付きでAPIサーバに送信する必要があるなど、フロントでハイフン付き電話番号に変換する機会があると思います。

GitHubのGoogleリポジトリに電話番号処理ライブラリ[libphonenumber](https://github.com/google/libphonenumber)があります。
こちらのJS版のデモページで、電話番号とカントリーコード（`JP`）を入力することで動作検証ができます。こちらのデモと同様の挙動を実現する想定です。
[Phone Number Parser Demo](https://htmlpreview.github.io/?https://github.com/google/libphonenumber/blob/master/javascript/i18n/phonenumbers/demo-compiled.html)

JS版の使い方を読むと、コンパイルなどの必要があり直接NPMから利用できずとても面倒です。本家の参照しているサードパーティライブラリを使います。

>Alternatives to our own versions:
Javascript: If you don't want to use our version, which depends on Closure, there are several other options, including https://github.com/catamphetamine/libphonenumber-js - a stripped-down rewrite, about 110 KB in size - and https://github.com/seegno/google-libphonenumber - a browserify-compatible wrapper around the original unmodified library installable via npm, which packs the Google Closure library, about 420 KB in size.

今回は執筆当時にDL数の多かった[google-libphonenumber](https://github.com/ruimarinho/google-libphonenumber)を利用します。

##動作環境
- TypeScript 3.9
- google-libphonenumber "3.2.15"
- NPMから利用

```
// npm
npm install google-libphonenumber
// Yarn
yarn add google-libphonenumber 
```

##サンプルコード
TypeScriptでサンプルコードを作成しましたが、変数宣言時の型定義を削除すれば、JavaScriptでも動作するかと思います。

```formatUtil.ts
import { PhoneNumberUtil, PhoneNumber, PhoneNumberFormat } from 'google-libphonenumber';

export class FormatUtil {
  public static formatTelNumber (value: string) {

    // 日本の国コード
    const region = 'JP';

    const util:PhoneNumberUtil = PhoneNumberUtil.getInstance();

    // 番号と地域を設定
    const number:PhoneNumber = util.parseAndKeepRawInput(value, region);

    // 電話番号の有効性チェック
    if (!util.isValidNumberForRegion(number, region)) {
      return null;
    }

    // ハイフン付きの形式で返却
    return util.format(number, PhoneNumberFormat.NATIONAL);
  }
}

```

##動作結果

```formatUtil.spec.ts
import { FormatUtil } from '~/util/FormatUtil';

describe('FormatUtil', () => {
  test('formatTelNumber', () => {
    // 携帯電話番号
    expect(FormatUtil.formatTelNumber('09012345678')).toEqual('090-1234-5678');
    expect(FormatUtil.formatTelNumber('08099998888')).toEqual('080-9999-8888');
    expect(FormatUtil.formatTelNumber('07033336666')).toEqual('070-3333-6666');
    expect(FormatUtil.formatTelNumber('09011111111')).toEqual('090-1111-1111');
    // 大阪
    expect(FormatUtil.formatTelNumber('0611112222')).toEqual('06-1111-2222');
    // 愛知
    expect(FormatUtil.formatTelNumber('0529991111')).toEqual('052-999-1111');
    // 千葉
    expect(FormatUtil.formatTelNumber('0431234567')).toEqual('043-123-4567');
    // 福岡
    expect(FormatUtil.formatTelNumber('0921234567')).toEqual('092-123-4567');
    // 東京
    expect(FormatUtil.formatTelNumber('0312345678')).toEqual('03-1234-5678');
    // IP電話
    expect(FormatUtil.formatTelNumber('05012345678')).toEqual('050-1234-5678');

    // 無効番号
    expect(FormatUtil.formatTelNumber('05012')).toEqual(null);
    expect(FormatUtil.formatTelNumber('09000000000')).toEqual(null);
    expect(FormatUtil.formatTelNumber('99999999999')).toEqual(null);
  });
});
```

##参考
[GitHub Google/libphonenumber](https://github.com/google/libphonenumber)
[GitHub ruimarinho/google-libphonenumber](https://github.com/ruimarinho/google-libphonenumber)
[Qiita JavaScriptで電話番号のバリデーション＆自動フォーマット](https://qiita.com/the_red/items/fcedd5033530b7ff7ee7)