JavaScriptの標準組み込みオブジェクトにIntlオブジェクトがあります。国際化APIの名前空間で、localeに依存した数値のフォーマットや分かち書きを行うプロパティを持ちます。
この記事ではそんなプロパティの1つであるDisplayNamesについて解説します。
DisplayNames
DisplayNamesは言語、地域、文字体系をlocaleに応じて翻訳するためのオブジェクトです。
const regionNames = new Intl.DisplayNames('ja-JP', { type: 'region' });
// アメリカ合衆国
console.log(regionNames.of('US'));
DisplayNamesを初期化するタイミングで扱いたいlocaleと翻訳する文字列の種類を指定します。
const regionNames = new Intl.DisplayNames('ja-JP', { type: 'region' });
第2引数では翻訳する文字列の種類のほかにオプションを渡せます。
const regionNames = new Intl.DisplayNames(
'ja-JP',
{
localeMatcher: 'lookup',
style: 'narrow',
type: 'language',
code: 'none',
languageDisplay: 'standard',
},
);
localeMathcerは第一引数のlocaleが配列で複数渡ってきた時の優先順位の付け方を決めます。デフォルトではbest fitで他にlookupを指定できます。
best fitはリクエストやランタイムを用いて最適なlocaleを決定し、lookupを指定した場合はLookupのアルゴリズムによって決定されます。
styleは翻訳後の文字の長さを指定します。デフォルトはlongです。他の選択肢としてはshortとnarrowが存在します(narrowが有効になる例を見つけられませんでした🙏)。
const languageNames1 = new Intl.DisplayNames(
'ja-JP',
{
type: 'language',
},
);
const languageNames2 = new Intl.DisplayNames(
'ja-JP',
{
type: 'language',
style: 'short',
},
);
const languageNames3 = new Intl.DisplayNames(
'ja-JP',
{
type: 'language',
style: 'narrow',
},
);
// 英語(イギリス)
console.log(languageNames1.of('en-GB'));
// 英語(英国)
console.log(languageNames2.of('en-GB'));
// 英語(英国)
console.log(languageNames3.of('en-GB'));
typeは翻訳する文字の種類を指定します。このオプションは指定が必須です。存在する種類はlanguage、region、script、currency、calendar、dateTimeFieldです。
const languageNames = new Intl.DisplayNames('ja-JP', { type: 'language' });
// フランス語
console.log(languageNames.of('fr'));
const regionNames = new Intl.DisplayNames('ja-JP', { type: 'region' });
// アメリカ合衆国
console.log(regionNames.of('US'));
const scriptNames = new Intl.DisplayNames(
'ja-JP',
{
type: 'script',
},
);
// 仮名
console.log(scriptNames.of('Hrkt'));
const currencyNames = new Intl.DisplayNames('ja-JP', { type: 'currency' });
// ユーロ
console.log(currencyNames.of('EUR'));
const calendarNames = new Intl.DisplayNames('ja-JP', { type: 'calendar' });
// 中華民国暦
console.log(calendarNames.of('roc'));
const dateTimeFieldNames = new Intl.DisplayNames('ja-JP', { type: 'dateTimeField' });
// 年
console.log(dateTimeFieldNames.of('year'));
fallbackは翻訳先がない時に返す値を決めます。デフォルトではcodeで受け取った値をそのまま返します。この他にはnoneがあり、undefiendを返します。
const regionNames1 = new Intl.DisplayNames(
'ja-JP',
{
type: 'region',
},
);
const regionNames2 = new Intl.DisplayNames(
'ja-JP',
{
type: 'region',
fallback: 'none',
},
);
// hk
regionNames1.of('hk');
// undefined
regionNames2.of('hk');
languageDisplayはtypeがlanguageの場合にのみ使えます。デフォルトは"dialectで現地での呼ばれ方に翻訳されます。standardでは一般的な表現になります。
const languageNames1 = new Intl.DisplayNames('ja-JP', {
type: 'language',
});
const languageNames2 = new Intl.DisplayNames('ja-JP', {
type: 'language',
languageDisplay: 'standard',
});
// アメリカ英語
console.log(languageNames1.of('en-US'));
// 英語(アメリカ合衆国)
console.log(languageNames2.of('en-US'));
上記の例からもわかるようにDisplayNamesオブジェクトの作成後はofメソッドに渡した文字列が翻訳されます。typeに対応した文字列を渡せなかった場合はエラーが発生するので注意してください。
typeに対応する文字列はECMAScriptの仕様書で定義されています。
localeが対応していることを確認する
DisplayNamesオブジェクトに渡すlocaleは静的メソッドであるsupportedLocalesOfを用いて確認できます。引数はDisplayNamesオブジェクトのコンストラクタと同じです。
// ['ja', 'ja-JP']
console.log(
Intl.DisplayNames.supportedLocalesOf(
['ja', 'JP', 'ja-JP'],
)
);
第二引数にはlocaleMatcherを渡せます。typeはコンストラクタでは必須ですが、ここでは必要ありません。
// ['ja', 'ja-JP']
console.log(
Intl.DisplayNames.supportedLocalesOf(
['ja', 'JP', 'ja-JP'],
{
localeMatcher: 'lookup',
}
)
);
有効なオプションを確認する
resolvedOptionsはDisplayNamesオブジェクトを作成したときに有効となった設定を表示します。
const languageNames = new Intl.DisplayNames(['ja-JP', 'en-US'], {
type: 'language',
languageDisplay: 'standard',
});
/*
* {
* locale: 'ja-JP',
* style: 'long',
* type: 'language',
* fallback: 'code',
* languageDisplay: 'standard'
* }
*/
console.log(languageNames.resolvedOptions());
localeは渡したままの状態ではなくlocaleMatcherで決められたものが渡されます。