Mastering the integration of TypeScript with vue-i18n and arrays

We have developed a basic landing page that showcases countries specified in a Vue-i18n language.json file. While the functionality is working well, we are encountering the following TypeScript errors:

[vue-tsc] Property 'code' does not exist on type 'never'.

[vue-tsc] Property 'name' does not exist on type 'never'.

It appears that the properties of a country cannot be found in the .json file. Even though we have defined the MessageSchema as enUS, per the instructions in the official documentation. No errors are present for other strings in the lang.json files; only when dealing with a list or array, it seems to not default to String.

You can access a test version in a CodeSandBox here. Below are the key files.

File 'en-US.json'

 "page": {
    "landing": {
      "title": { "selectCountry": "Select your country" },
      "countries": [
        { "code": "BEL", "name": "Belgium" },
        { "code": "NLD", "name": "The Netherlands" }
      ]
    },

File '/boot/i18n.ts'

import enUS from 'src/i18n/en-US.json'
import nlBE from 'src/i18n/nl-BE.json'

export default boot(({ app }) => {
  // Type-define 'enUS' as the master schema for the resource
  type MessageSchema = typeof enUS

  const i18n = createI18n<[MessageSchema], 'en-US' | 'nl-BE'>({
    legacy: false,
    locale: Quasar.lang.getLocale(),
    fallbackLocale: 'en-US',
    messages: { 'en-US': enUS, 'nl-BE': nlBE },
  })

  app.use(i18n)
})

File 'LandingPage.vue'

<template>
  <q-page>
    <div>
      <q-card v-for="country in $tm('page.landing.countries')" :key="country.code">
        <q-card-section>
          <q-card-section>
            <div> {{ $rt(country.name) }} </div>
          </q-card-section>
        </q-card-section>
      </q-card>
    </div>
  </q-page>
</template>

Your assistance is greatly appreciated.

Answer №1

Utilizing template injections like $t and $tm may not handle types correctly, regardless of whether you are using JSON, .ts, or .yaml files to store i18n data.

To ensure proper types, it is recommended to access the desired methods through useI18n(). See the example below:

<template>
  <q-page>
    <div>
      <q-card v-for="country in tm('page.landing.countries')" :key="country.code">
        <q-card-section>
          <q-card-section>
            <div> {{ rt(country.name) }} </div>
          </q-card-section>
        </q-card-section>
      </q-card>
    </div>
  </q-page>
</template>

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

const { tm, rt } = useI18n();
</script>

Therefore, when working with TypeScript, it is advisable to always explicitly use useI18n instead of relying on template injections. This approach will provide better autocompletion for i18n keys, such as t('will-get-autocomplete-here')

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Handling typeError in Vue.js JavaScript filter for object manipulation

I need to sort an object based on state names (e.g. Berlin, Bayern ...). Below is the API response I received. "states":{ "Bayern":{ "total":13124737, "rs":"09", "va ...

The title must not include the phrase "Automated transfer from npm to vue application."

Utilizing npm to download JavaScript libraries is convenient, although integrating them into a Vue app can be quite challenging. I am unsure if there is an established method for this, as various approaches are found online. Sometimes these libraries are ...

How can I retrieve the express Application within a REST API?

After reviewing Massive's documentation and learning that saving the connection object to Express's application settings can help reduce database connection execution time, I encountered a problem. How can one access the Express app variable when ...

How can I fetch and reference multiple local JSON files in Vue using Axios?

I am currently utilizing vue for prototyping some HTML components. Is there a method to make Vue detect two separate JSON files? vue.js var vm = new Vue({ el: '#douglas-laing', data: { products: [], contentPanels: [] }, created() ...

Issues encountered when attempting to run a local Dockerized Vite + Vue frontend deployment

Trying to utilize docker-compose for running a local FE Vite + Vue project. With references from various tutorials and posts, like this one here. The docker-compose setup seems to be functioning well, starting the FE server but not loading in Chrome. Docke ...

Having trouble getting navigation to work using react-navigation and typescript in a react-native project?

Currently, I am exploring the use of TypeScript in my React Native project for the first time. While I have a basic understanding of TypeScript, I am encountering some issues with third-party libraries like react-navigation. My project consists of parent ( ...

Solving TypeScript circular dependencies using () => TypeName

Recently encountered circular reference issues with Typescript. Suggestions provided on https://github.com/microsoft/TypeScript/issues/27519 recommend using () => TypeName. However, I am unsure how to effectively utilize the variable in this context. ex ...

Typescript is struggling to accurately infer extended types in some cases

My goal is to optimize the body of a NextApiRequest for TypeScript. I currently have this code snippet: // This is a type from a library I've imported export interface NextApiRequest { query: Partial<{ [key: string]: string | string[]; ...

How to retrieve the length of an array stored in the data object of a Vue instance

Having trouble retrieving the length of an array in vue. The array is located in the data object like so: data() { return { slides: [ { image: require("@/assets/img/carousel/couple.jpg"), caption: "A coupl ...

Is there a way to utilize ng-if within a button to reveal the remaining portion of a form using TypeScript?

Can anyone help me figure out how to make the rest of my form appear when I click on a button? I think I need to use Ng-if or something similar. Here is the code for the button: <button type = "button" class="btn btn-outline-primary" > Données du ...

Exploring the power of nesting views using *ngFor in Ionic framework

I am looking to design a screen that features nested views using the *ngFor loop. The data I have is in a two-dimensional array format and I want to iterate through it to display the same view for each row within each section. It should look something like ...

Leverage the key-value pairs in JSON to automatically suggest types within the function parameters

If we have data structured like this: { "key1": "hardcoded string", "key2": "another hardcoded string", } Imagine a function with 2 parameters where the first parameter should refer to key1 and the second to i ...

Angular2 - Creating PDF documents from HTML content with jspdf

For my current project, I am in need of generating a PDF of the page that the user is currently viewing. To accomplish this task, I have decided to utilize jspdf. Since I have HTML content that needs to be converted into a PDF format, I will make use of th ...

What is the significance of a React Functional Component returning JSX.IntrinsicElements?

I stumbled upon this React functional component in a particular documentation import React, { useState, useEffect } from 'react'; import { fabric } from 'fabric'; interface ITextProps { id: string; options: fabric.ITextboxOptions; ...

Encountering an issue while attempting to initiate a nested array: "Cannot assign a value to an optional property access in the left-hand side of an assignment expression."

I am dealing with an object that contains nested arrays, structured like this: export class OrdenCompra { public id?: number, public insumos?: OrdenCompraInsumo[], } export class OrdenCompraInsumo { id?: number; traslados?: IImpuestoTraslado[]; } export ...

Resolving the Angular NG0100 Error: Troubleshooting the ExpressionChangedAfterItHasBeenCheckedError

I am currently working on implementing a dialog component that takes in data through its constructor and then utilizes a role-based system to determine which parts of the component should be displayed. The component code snippet looks like this: export cl ...

Using VueJS: Passing a variable with interpolation as a parameter

Is there a way to pass the index of the v-for loop as a parameter in my removeTask function? I'm looking for suggestions on how to achieve this. <ol class="list-group"> <li v-for="task in tasks" class="list-group-item"> ...

Incorporating a new function into a TypeScript (JavaScript) class method

Is it possible to add a method to a method within a class? class MyClass { public foo(text: string): string { return text + ' FOO!' } // Looking for a way to dynamically add the method `bar` to `foo`. } const obj = new MyCl ...

Tips for obtaining the unique array element lengths in a JSON array

How can I determine the number of active users in a JSON array that includes both active and inactive user statuses? { "body": { "existing_users": [ { "product": "Pack-2", "user_statu ...

VueJS / v-html is displaying a blank page (Bokeh-html)

Especially as a newcomer to VueJS, I am currently in the process of trying to showcase a local HTML file within the Vue Application. The method I'm using to fetch the HTML file involves Axios, here's how it goes: <template> <div> ...