TypeScript サポート
対応バージョン
🆕 9.2+
VueI18n は、ロケールメッセージ、日時フォーマット、数値フォーマットなどのリソースを使用します。 特に、ロケールメッセージは json ファイルなどとして i18n リソースとして外部化でき、ローカライズサービスを使用して翻訳者と協力できます。そしてこれらのリソースをインポートして協力できます。
ローカライズサービスとの連携により、スムーズなローカリゼーションワークフローを実現するためには、外部化された i18n リソースのローカリゼーション不足やリソース定義不足を防ぐ必要があるかもしれません。 開発時には、翻訳関数 $t の使用におけるキー文字列の誤りを防ぐことで、開発体験を損ないたくないでしょう。
スキーマによる型安全なリソース
TypeScript を使用することで、リソーススキーマで型安全なリソースをサポートできます。
createI18n での型安全なリソース
createI18n オプションで定義された messages の型安全なリソースを定義する例です。
ロケールメッセージリソース:
{
"world": "the world!"
}アプリケーションエントリポイント:
import { createI18n } from 'vue-i18n'
import enUS from './locales/en-US.json'
// 'en-US' をリソースのマスタースキーマとして型定義
type MessageSchema = typeof enUS
const i18n = createI18n<[MessageSchema], 'en-US' | 'ja-JP'>({
locale: 'en-US',
messages: {
'en-US': enUS
}
})上記コードは、createI18n の messages オプションで指定された en-US メッセージリソースから型を定義します。この定義された型は、VueI18n で処理されるメッセージリソースのマスターライクなスキーマです。つまり、アプリケーション内で 単一の真実のソース リソースとして定義できるということです。メッセージリソースからスキーマとして定義された型を createI18n の型パラメータの最初の引数として指定することで、他のロケールで型安全なリソースを定義できます。
createI18n の型パラメータの第二引数は処理するロケールです。これにより、第一引数で指定されたリソースの型に基づいて、第二引数で指定された各ロケールに対して型チェックが実行されます。上記コード例では、en-US と ja-JP がメインロケールとして指定されており、これは locale オプションにも指定されています。この状態で Typescript をコンパイルすると、messages オプションに ja-JP リソースが定義されていないことを確認するためのエラーが発生します。
$ npx tsc
npx tsc
src/main.ts:11:3 - error TS2741: Property '"ja-JP"' is missing in type '{ 'en-US': { world: string; }; }' but required in type '{ "en-US": { world: string; }; "ja-JP": { world: string; }; }'.
11 messages: {
~~~~~~~~
node_modules/vue-i18n/dist/vue-i18n.d.ts:712:5
712 messages?: {
~~~~~~~~
The expected type comes from property 'messages' which is declared here on type 'I18nOptions<{ message: { world: string; }; datetime: DateTimeFormat; number: NumberFormat; }, { messages: "en-US"; datetimeFormats: "en-US"; numberFormats: "en-US"; } | { ...; }, ComposerOptions<...> | VueI18nOptions<...>>'
Found 1 error.Visual Studio Code をエディターとして使用している場合、Typescript コンパイルを実行する前に、以下のエラーでリソース定義の省略をエディター上で気づくことができます。


useI18n での型安全なリソース
型安全なリソースは createI18n だけでなく、Composition API とともに使用される useI18n でコンポーネントごとに定義できます。
ローカルメッセージに加えて、リソースタイプ定義には日付時間フォーマットと数値フォーマットも含めることができます。
以下は、useI18n でロケールメッセージと数値フォーマットの型安全なリソースをコンポーネントごとに定義するコード例です。
Vue コンポーネントでインポートするロケールメッセージ:
{
"messages": {
"hello": "Hello, {name}!"
}
}型安全なリソースを持つ Vue コンポーネント:
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import enUS from './en-US.json' // Vue コンポーネント用のロケールメッセージをインポート
// Vue コンポーネント用のメッセージスキーマを定義
type MessageSchema = typeof enUS
// Vue コンポーネント用の数値フォーマットスキーマを定義
type NumberSchema = {
currency: {
style: 'currency'
currencyDisplay: 'symbol'
currency: string
}
}
/*
* 型パラメータの最初にオブジェクトリテラルでスキーマを指定できます
* 型パラメータについては、http://vue-i18n.intlify.dev/api/composition.html#usei18n を参照してください
*/
const { t, n } = useI18n<{
message: MessageSchema,
number: NumberSchema
}, 'en-US'>({
inheritLocale: true,
messages: {
'en-US': enUS
},
numberFormats: {
'en-US': {
currency: {
style: 'currency',
currencyDisplay: 'symbol',
currency: 'USD'
}
}
}
})
</script>
<template>
<p>message: {{ t('messages.hello', { name: 'kazupon' }) }}</p>
<p>currency: {{ n(1000, 'currency') }}</p>
</template>上記コードでは、useI18n の最初の型パラメータとして定義されたスキーマを指定することで、ロケールメッセージと数値フォーマットの未定義リソースを TypeScript でチェックできます。また、第二型パラメータに定義するロケールを指定することで、未定義のロケールを TypeScript でチェックできます。
制限事項
- SFC の i18n カスタムブロックでは型安全性がサポートされていません。今後の対応予定です。
- 現在は
JSONフォーマットのみをサポートしています。
これまで記述したコードは example として利用可能です。確認してみてください!
型安全をサポートする API
他の API は、型安全なリソース操作のためにリソーススキーマを指定できる型パラメータをサポートしており、以下のようになります:
getLocaleMessagesetLocaleMessagemergeLocaleMessagegetDateTimeFormatsetDateTimeFormatmergeDateTimeFormatgetNumberFormatsetNumberFormatmergeNumberFormat
詳細については、以下の API ドキュメントページをご確認ください。
リソースキー補完のサポート
注意
リソースキー補完は Visual Studio Code を使用している場合にのみ使用できます
型安全なリソース定義のサポートとともに、VueI18n は Composition API でリソースキーを補完するための API(t や d など)を提供しています。
以下の例は、上記のローカルスコープ Vue コンポーネントで Visual Studio Code でリソースキーを補完する方法を示しています。

リソースキーの補完サポートにより、翻訳ミスを防止できます。
プロジェクトでの使用ケースとして、ローカルスコープを使わず、すべてグローバルスコープを使用する Vue コンポーネントがあるかもしれません。
そのようなケースでは、useI18n の型パラメータにグローバルスコープ用に定義されたスキーマを明示的に指定することで、リソースキーの補完をサポートできます。
グローバルスコープ用のスキーマを定義:
/**
* リソーススキーマを定義
*/
import enUS from './en-US.json'
// メッセージスキーマをマスターメッセージスキーマとして定義
export type MessageSchema = typeof enUS
// 数値フォーマットスキーマを定義
export type NumberSchema = {
currency: {
style: 'currency'
currencyDisplay: 'symbol'
currency: string
}
}それから、定義されたスキーマをインポートし、useI18n の型パラメータとして使用します。以下のような Vue コンポーネントのように:
<script lang="ts">
import { useI18n } from 'vue-i18n'
// グローバルスコープ用のリソーススキーマをインポート
import type { MessageSchema, NumberSchema } from '../locales/schema'
const { t, n } = useI18n<{ message: MessageSchema, number: NumberSchema }>({
useScope: 'global'
})
</script>
<template>
<p>message: {{ t('hello') }}</p>
<p>currency: {{ n(1000, 'currency') }}</p>
</template>結果として、t や n といった VueI18n が提供する API でリソースキーの補完を使用できるようになります。
注意
レガシーモード、および Composition API の globalInjection: true によってコンポーネントに注入される $t や $d などの API のリソースキー補完には、明示的に型パラメータを指定する必要があります。
詳細については API ドキュメントを参照してください。 https://vue-i18n.intlify.dev/api/injection.html
グローバルリソーススキーマ型定義
VueI18n では、TypeScript の機能を使ってインターフェースを拡張することで、グローバルスコープレベルでリソースタイプを定義できます。
プロジェクト全体でリソースをグローバルスコープとして使用する場合、型安全なリソースを簡単に扱うのが非常に便利です。
VueI18n は以下のインターフェースを提供しています:
DefineLocaleMessage:ロケールメッセージ用のグローバルスキーマを定義するインターフェースDefineDateTimeFormat:日時フォーマット用のグローバルスキーマを定義するインターフェースDefineNumberFormat:数値フォーマット用のグローバルスキーマを定義するインターフェース
これらのインターフェースと declare module を使用することで、VueI18n のためのグローバルスキーマを定義できます。
以下は d.ts に定義されたグローバルスキーマの例です:
/**
* 必要なインターフェースをインポートする必要があります
*/
declare module 'vue-i18n' {
// ロケールメッセージスキーマを定義
export interface DefineLocaleMessage {
hello: string
menu: {
login: string
}
errors: string[]
}
// 日時フォーマットスキーマを定義
export interface DefineDateTimeFormat {
short: {
hour: 'numeric'
minute: 'numeric'
second: 'numeric'
timeZoneName: 'short'
timezone: string
}
}
// 数値フォーマットスキーマを定義
export interface DefineNumberFormat {
currency: {
style: 'currency'
currencyDisplay: 'symbol'
currency: string
}
}
}declare module と VueI18n が提供するインターフェースを使用することで、グローバルリソースのスキーマを定義できます。
以前は、グローバルスコープリソースの型定義とともに createI18n と useI18n を使用する際に、それぞれを型パラメータとして指定する必要がありました。 この方法ではそれをする必要はありません。
以下は createI18n での例です:
import { createI18n, type I18nOptions } from 'vue-i18n'
/**
* json からグローバルスコープ用のロケールメッセージリソースをインポート
*/
import enUS from './locales/en-US.json'
import jaJP from './locales/ja-JP.json'
const options: I18nOptions = {
legacy: false,
locale: 'ja-JP',
fallbackLocale: 'en-US',
messages: {
'en-US': enUS,
'ja-JP': jaJP
},
datetimeFormats: {
'ja-JP': {
short: {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
timeZoneName: 'short',
timezone: 'Asia/Tokyo'
}
}
},
numberFormats: {
'ja-JP': {
currency: {
style: 'currency',
currencyDisplay: 'symbol',
currency: 'JPY'
}
}
}
}
/**
* グローバル型定義付き i18n リソースで vue-i18n をセットアップ。
* `*.d.ts` で i18n リソーススキーマを定義した場合、これらは TypeScript でチェックされます。
*/
const i18n = createI18n<false, typeof options>(options)上記の createI18n の最初の型パラメータは、リソーススキーマの型を指定しません。上記は createI18n によって作成される i18n インスタンスの global プロパティの型ヒントのみを指定しています。 (false の場合は Composition API 用の Composer インスタンス、true の場合はレガシー API 用の VueI18n インスタンス)
createI18n の第二型パラメータはオプションの型ヒントを指定します。
Vue コンポーネントで使用される useI18n の場合、以下のようになります:
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
// グローバルスコープを使用
const { t, d, n } = useI18n({
inheritLocale: true
})
</script>
<template>
<p>`t` リソースキー補完: {{ t('menu.login') }}</p>
<p>`d` リソースキー補完: {{ d(new Date(), 'short') }}</p>
<p>`n` リソースキー補完: {{ n(1000, 'currency') }}</p>
</template>上記コードからわかるように、useI18n の型パラメータには何も指定する必要がありません。t、d、n などの API リソースキーを指定することなく補完できます。