Skip to content

Soporte de TypeScript

Versiones compatibles

🆕 9.2+

VueI18n utiliza los recursos, que incluyen mensajes locales, formatos de fecha y hora y formatos numéricos. Especialmente, los mensajes locales pueden ser externalizados como recursos i18n, tales como archivos json, para colaborar con traductores usando el servicio de localización, y estos recursos pueden ser importados para colaborar.

Para lograr un flujo de trabajo de localización fluido en conjunto con el Servicio de Localización, es posible que desee evitar la falta de localizaciones o definiciones de recursos faltantes para recursos i18n externalizados. Y en desarrollo, es posible que no quiera afectar la experiencia del desarrollador al prevenir errores de cadenas de texto al usar la función de traducción como $t.

Recursos seguros de tipo con esquema

Puede soportar recursos seguros de tipo con esquema de recurso usando TypeScript.

Recursos seguros de tipo en createI18n

El siguiente es un ejemplo de código para definir recursos seguros de tipo para messages definidos con la opción createI18n.

Recurso de mensajes locales:

json
{
  "world": "the world!"
}

Punto de entrada de la aplicación:

ts
import { createI18n } from 'vue-i18n'
import enUS from './locales/en-US.json'

// Definir 'en-US' como el esquema maestro para el recurso
type MessageSchema = typeof enUS

const i18n = createI18n<[MessageSchema], 'en-US' | 'ja-JP'>({
  locale: 'en-US',
  messages: {
    'en-US': enUS
  }
})

El código anterior define un tipo desde el recurso de mensaje en-US especificado en la opción messages de createI18n. Este tipo definido es un esquema tipo maestro para los recursos de mensaje manejados con VueI18n. Esto significa que puede definirlo como un recurso de única fuente de verdad en su aplicación. Puede definir un recurso seguro de tipo en otros idiomas especificando el tipo definido como esquema de un recurso de mensaje como primer argumento del parámetro de tipo de createI18n.

El segundo argumento del parámetro de tipo de createI18n es el idioma a manejar. Con esto, se realiza verificación de tipos para cada idioma especificado en el segundo argumento, basado en el tipo del recurso especificado en el primer argumento. En el ejemplo de código anterior, se especifican en-US y ja-JP como el idioma principal, que también está especificado en la opción locale. Si compila TypeScript en este estado, obtendrá el siguiente error para verificar que no se define ningún recurso ja-JP en la opción messages.

sh
$ 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.

Si usa Visual Studio Code como editor, puede notar que hay una omisión de definición de recurso en el editor con el siguiente error antes de ejecutar la compilación de TypeScript.

VSCode-Type-Error1VSCode-Type-Error2

Recursos seguros de tipo en useI18n

Los recursos seguros de tipo pueden definirse no solo con createI18n, sino también por componente con useI18n usado con la API de Composición.

Además de los mensajes locales, las definiciones del tipo de recurso también pueden incluir formatos de fecha y hora y formatos numéricos.

El siguiente es un ejemplo de código que define recursos seguros de tipo para mensajes locales y formatos numéricos por componente en useI18n.

Mensajes locales para importar en componentes Vue:

json
{
  "messages": {
    "hello": "¡Hola, {name}!"
  }
}

Componentes Vue con recursos seguros de tipo:

vue
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import enUS from './en-US.json' // importar mensajes locales para componente Vue

// definir esquema de mensaje para componente Vue
type MessageSchema = typeof enUS

// definir esquema de formato numérico para componente Vue
type NumberSchema = {
  currency: {
    style: 'currency'
    currencyDisplay: 'symbol'
    currency: string
  }
}

/*
 * Puede especificar su esquema definido con un literal de objeto en los primeros parámetros de tipo
 * Acerca del parámetro de tipo, vea 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>mensaje: {{ t('messages.hello', { name: 'kazupon' }) }}</p>
  <p>moneda: {{ n(1000, 'currency') }}</p>
</template>

En los códigos anteriores, especificando el esquema definido como el primer parámetro de tipo de useI18n, puede usar TypeScript para verificar recursos indefinidos para mensajes locales y formatos numéricos. Además, especificando el idioma a definir en el segundo parámetro de tipo, TypeScript puede verificar idiomas indefinidos.

Limitación

  • El soporte de seguridad de tipo no está disponible para bloques i18n personalizados en SFC. Planeamos admitirlo en el futuro.
  • Actualmente solo se admite el formato JSON.

El código descrito hasta ahora está disponible como ejemplo. ¡Véalo!

APIs de soporte de seguridad de tipo

Otras APIs admiten un parámetro de tipo que le permite especificar el esquema de un recurso para manipulación segura de tipo de recursos, tales como:

  • getLocaleMessage
  • setLocaleMessage
  • mergeLocaleMessage
  • getDateTimeFormat
  • setDateTimeFormat
  • mergeDateTimeFormat
  • getNumberFormat
  • setNumberFormat
  • mergeNumberFormat

Para más detalles, consulte las siguientes páginas de documentación de API.

Soporte de completado de claves de recursos

AVISO

El completado de claves de recursos puede usarse si está utilizando Visual Studio Code

Junto con el soporte para definiciones de recursos seguras de tipo, VueI18n ahora proporciona APIs como t y d para interpolar claves de recursos en la API de Composición.

Lo siguiente indica cómo interpolar claves de recursos en Visual Studio Code para el componente Vue con ámbito local descrito anteriormente.

VSCode-Resource-Completion

El soporte de interpolación de claves de recursos puede prevenir la falta de traducciones.

En casos de uso en su proyecto, puede tener componentes Vue que no usan ámbito local, sino que usan ámbito global para todo.

Para ese caso de uso, también puede admitir la interpolación de claves de recursos especificando explícitamente el esquema definido para el ámbito global en el parámetro de tipo de useI18n.

Definir esquema para ámbito global:

ts
/**
 * definir el esquema de recurso
 */

import enUS from './en-US.json'

// definir esquema de mensaje como esquema de mensaje maestro
export type MessageSchema = typeof enUS

// definir esquema de formato numérico
export type NumberSchema = {
  currency: {
    style: 'currency'
    currencyDisplay: 'symbol'
    currency: string
  }
}

Entonces, simplemente importe el esquema definido y úselo como parámetro de tipo de useI18n, tal como en el siguiente componente Vue:

vue
<script lang="ts">
import { useI18n } from 'vue-i18n'

// importar esquema de recurso para ámbito global
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>

Como resultado, puede usar la interpolación de claves de recursos en las APIs proporcionadas por VueI18n, tales como t y n.

AVISO

Modo Legacy, e interpolación de claves de recursos de APIs tales como $t y $d, que son inyectados en Componentes por globalInjection: true de la API de Composición, requieren especificar explícitamente parámetros de tipo.

Para más detalles, consulte la documentación de la API. https://vue-i18n.intlify.dev/api/injection.html

Definición de tipo de esquema de recursos globales

En VueI18n, puede definir tipos de recursos en el nivel de ámbito global usando la característica de extensión de interfaces de TypeScript.

Si su proyecto usa todos los recursos en ámbito global, es muy conveniente manejar recursos seguros de tipo fácilmente.

VueI18n proporciona las siguientes interfaces:

  • DefineLocaleMessage: Interfaz para definir globalmente el esquema para mensajes locales
  • DefineDateTimeFormat: Interfaz para definir globalmente el esquema para formatos de fecha y hora
  • DefineNumberFormat: Interfaz para definir globalmente el esquema para formatos numéricos

Con el uso de estas interfaces y declare module, puede definir un esquema global para VueI18n.

El siguiente es un ejemplo de esquema global definido en d.ts:

ts
/**
 * necesita importar algunas interfaces
 */



declare module 'vue-i18n' {
  // definir el esquema de mensajes locales
  export interface DefineLocaleMessage {
    hello: string
    menu: {
      login: string
    }
    errors: string[]
  }

  // definir el esquema de formato de fecha y hora
  export interface DefineDateTimeFormat {
    short: {
      hour: 'numeric'
      minute: 'numeric'
      second: 'numeric'
      timeZoneName: 'short'
      timezone: string
    }
  }

  // definir el esquema de formato numérico
  export interface DefineNumberFormat {
    currency: {
      style: 'currency'
      currencyDisplay: 'symbol'
      currency: string
    }
  }
}

Con el uso de declare module y la interfaz proporcionada por VueI18n, puede definir el esquema para recursos globales.

Anteriormente, al usar createI18n y useI18n con definiciones de tipo para recursos de ámbito global, era necesario especificar cada uno como parámetro de tipo. De esta manera, no necesita hacerlo.

El siguiente es un ejemplo con createI18n:

ts
import { createI18n, type I18nOptions } from 'vue-i18n'

/**
 * importar recurso de mensajes locales desde json para ámbito global
 */
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'
      }
    }
  }
}

/**
 * configurar vue-i18n con recursos i18n con definición de tipo global.
 * si define el esquema de recurso i18n en su `*.d.ts`, éstos se verificarán con TypeScript.
 */
const i18n = createI18n<false, typeof options>(options)

El primer parámetro de tipo de createI18n anterior no especifica el tipo que es el esquema del recurso. Lo anterior solo especifíca una pista de tipo para la propiedad global de la instancia i18n creada por createI18n. (Es para la API de Composición, si false, el tipo es una instancia Composer, si true, el tipo es una instancia VueI18n para la API Legacy)

El segundo parámetro de tipo de createI18n especifica una pista de tipo para las opciones.

En el caso del uso de useI18n por componentes Vue, parece así:

vue
<script setup lang="ts">
import { useI18n } from 'vue-i18n'

// usar ámbito global
const { t, d, n } = useI18n({
  inheritLocale: true
})
</script>

<template>
  <p>`t` resource key completion: {{ t('menu.login') }}</p>
  <p>`d` resource key completion: {{ d(new Date(), 'short') }}</p>
  <p>`n` resource key completion: {{ n(1000, 'currency') }}</p>
</template>

Como puede ver en el código anterior, no necesita especificar nada para el parámetro de tipo de useI18n. Puede interpolar claves de recursos de API tales como t, d y n sin especificarlos.