Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

global $t show issue #1403

Open
4 tasks done
JonDelWeb opened this issue May 15, 2023 · 33 comments
Open
4 tasks done

global $t show issue #1403

JonDelWeb opened this issue May 15, 2023 · 33 comments
Labels
Status: Need More Info Lacks enough info to make progress typescript

Comments

@JonDelWeb
Copy link

JonDelWeb commented May 15, 2023

Reporting a bug?

The global variable "$t" show issue 'Property '$t' does not exist on type' in vue template

My ./i18n/index.ts files :

  import { createI18n } from 'vue-i18n';
  
  import fr from "./locales/fr.json";
  type MessageSchema = typeof fr
  
  export default createI18n<[MessageSchema], 'fr'>({
    allowComposition: true,
    locale: import.meta.env.VITE_DEFAULT_LOCALE,
    fallbackLocale: import.meta.env.VITE_FALLBACK_LOCALE,
    legacy: false,
    messages: {
      'fr': fr,
    },
  })  

My main.ts file :

import { createApp } from 'vue';
import { createPinia } from 'pinia';

import i18n from "./i18n";

import App from './App.vue';
import router from './router';

import './index.css';

const app = createApp(App)

app.use(i18n)
app.use(createPinia())
app.use(router)

app.mount('#app')

My template file :

<nav class="flex flex-row mx-2 m-0.5">
      <RouterLink class="px-1" to="login">{{  $t("auth.login") }}</RouterLink> /
       <RouterLink class="px-1" to="register">{{  $t("auth.register") }}</RouterLink>
</nav>

Expected behavior

No issue :D

Reproduction

  1. create new vue3 project
  2. install "vue-i18n": "^9.3.0-beta.17",
  3. create json files
  4. use $t in template

System Info

System:
    OS: Linux 5.15 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish)
    CPU: (4) x64 Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz
    Memory: 6.79 GB / 15.50 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 18.16.0 - /usr/bin/node
    npm: 8.19.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 113.0.5672.92
    Firefox: 113.0.1
  npmPackages:
    @intlify/unplugin-vue-i18n: ^0.10.0 => 0.10.0 
    @vitejs/plugin-vue: ^4.2.1 => 4.2.2 
    @vitejs/plugin-vue-jsx: ^3.0.1 => 3.0.1 
    @vue/eslint-config-prettier: ^7.1.0 => 7.1.0 
    @vue/eslint-config-typescript: ^11.0.3 => 11.0.3 
    @vue/tsconfig: ^0.3.2 => 0.3.2 
    vite: ^4.3.4 => 4.3.5 
    vue: ^3.2.47 => 3.3.1 
    vue-i18n: ^9.3.0-beta.17 => 9.3.0-beta.14-77e850b 
    vue-moment: ^4.1.0 => 4.1.0 
    vue-router: ^4.1.6 => 4.2.0 
    vue-tsc: ^1.6.4 => 1.6.4

Screenshot

No response

Additional context

No response

Validations

@JonDelWeb JonDelWeb added the Status: Review Needed Request for review comments label May 15, 2023
@dodo1708
Copy link

dodo1708 commented May 16, 2023

I'm having the same issue.
Adding

"types": "./dist/vue-i18n.d.ts",

to

"exports": {
    ".": {
      "types": "./dist/vue-i18n.d.ts",
      "import": {
        "node": "./index.mjs",
        "default": "./dist/vue-i18n.esm-bundler.js"
      },
      "require": "./index.js"
    },
    "./dist/*": "./dist/*",
    "./index.mjs": "./index.mjs",
    "./package.json": "./package.json"
  },

in the vie-i18n package.json fixed the issue for me when running it locally.

@g1eny0ung
Copy link
Contributor

g1eny0ung commented May 23, 2023

I have the same problem. The situation for me is that I upgrade vue to v3.3 with pnpm, the package with the old vue version seems to be confusing with the new one, and running pnpm dedupe solves this problem.

@oikalyptus
Copy link

I have the same issue. dedupe won’t fix it for me.
I ran patch-package with @dodo1708 changes and it works.

@DominikWeickgenannt
Copy link

I was getting this error even with version 9.3.0-beta.17.
Deleting the node_modules & dist folders and rebuilding solved this for me.

@kazupon kazupon added typescript Status: Need More Info Lacks enough info to make progress and removed Status: Review Needed Request for review comments labels May 30, 2023 — with Volta.net
Copy link
Member

kazupon commented Jun 2, 2023

Thank you for your reporting!

Issue template said:

Please provide a link to a repo that can reproduce the problem you ran into. A minimal reproduction is required (Why?). If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "Status: Need More Info" label. If no reproduction is provided after 5 days, it will be closed.

Could you give us your minimal reproduction with github repo or stackbliz please? 🙏

@JonDelWeb
Copy link
Author

No problem, I will try to do it this week-end... ;)

@mats852
Copy link

mats852 commented Jun 6, 2023

Hi @kazupon, I cannot share my repository, but I can provide further details, I have the same problem.

Here is the full error message

error TS7016: Could not find a declaration file for module 'vue-i18n'. '<redacted>/node_modules/vue-i18n/dist/vue-i18n.esm-bundler.js' implicitly has an 'any' type.
  There are types at '<redacted>/node_modules/vue-i18n/dist/vue-i18n.d.ts', but this result could not be resolved when respecting package.json "exports". The 'vue-i18n' library may need to update its package.json or typings.

@leighwilliams
Copy link

I ran in to this going from 9.2.2 to 9.3.0-beta-19.

With 9.2.2 in node_modules/vue-i18n/dist/vue-i18n.d.ts there is:

declare module '@vue/runtime-core' {
    ...
    $t<
      Key extends string,
      DefinedLocaleMessage extends RemovedIndexResources<DefineLocaleMessage> = RemovedIndexResources<DefineLocaleMessage>,
      Keys = IsEmptyObject<DefinedLocaleMessage> extends false
        ? PickupPaths<{
            [K in keyof DefinedLocaleMessage]: DefinedLocaleMessage[K]
          }>
        : never,
      ResourceKeys extends Keys = IsNever<Keys> extends false ? Keys : never
    >(
      key: Key | ResourceKeys | Path
    ): TranslateResult
    ...
}

With 9.3.0-beta-19 there is no such section within node_modules/vue-i18n/dist/vue-i18n.d.ts. The entire declare module '@vue/runtime-core' { ... } is missing.

@oognuyh
Copy link

oognuyh commented Jun 15, 2023

The same issue with 9.3.0-beta-19, so I downgraded to 9.3.0-beta-18.

@dkern
Copy link

dkern commented Jun 28, 2023

I'm on 9.2.2 using vite and typescript and when building it shows the error below. When using the development server, everything is fine. But building throws this error:

error TS2339: Property '$t' does not exist on type '{ $: ComponentInternalInstance; ...

@dkern
Copy link

dkern commented Jun 28, 2023

@kazupon
I can also confirm that adding types to the package.json fixes the issue for me. v9.3.0-beta.19 is not working.

  "exports": {
    ".": {
      "types": "./dist/vue-i18n.d.ts",
      // ...
    },
  },

@dkern
Copy link

dkern commented Jun 28, 2023

I was able to suppress this warning with a custom typescript definition. Therefore it's not needed to change the package.json in node_modules. Of course, this is not a real fix, but at least I can build the project again.

i18n.d.ts:

export {};

declare module 'vue' {
  interface ComponentCustomProperties {
    $t: (key: string) => string;
    $tm: (key: string) => []|{[p: string]: any};
  }
}

If you use more/other function of i18n you may need to add the to the interface.

@gcharest
Copy link

It's probably just another workaround for the moment but I specifically referenced the types path and declared the vue-i18n module in the env.d.ts file:

env.d.ts

/// <reference types="vite/client" /> 
/// <reference path="node_modules/vue-i18n/dist/vue-i18n.d.ts" />
declare module 'vue-i18n'

@bkis
Copy link

bkis commented Aug 7, 2023

I was able to suppress this warning with a custom typescript definition. Therefore it's not needed to change the package.json in node_modules. Of course, this is not a real fix, but at least I can build the project again.

i18n.d.ts:

export {};

declare module 'vue' {
  interface ComponentCustomProperties {
    $t: (key: string) => string;
    $tm: (key: string) => []|{[p: string]: any};
  }
}

The problem with this is that it only fixes the most simple calls to t: Pass a string, get a string back. But there are a number of overloads, for example for passing key-value pairs for inserting values into the message like in $t('admin.texts.levels.tipInsertLevel', { n: level + 1 }).

I was able to also cover these by copying the type definition directly from node_modules/vue-i18n/dist/vue-i18n.d.ts (i'm on 9.3.0-beta.25) and using them in way you suggested in i18n.d.ts in my project:

export {};

declare module 'vue' {
  interface ComponentCustomProperties {
    $t: ComposerTranslation<
      Messages,
      Locales,
      RemoveIndexSignature<{
        [K in keyof DefineLocaleMessage]: DefineLocaleMessage[K];
      }>
    >;
    $tm: Composition['tm'];
  }
}

Same thing you mentioned also applies here: If you are using other functions, you gotta add the type definitions for them. As I said, they can be found in node_modules/vue-i18n/dist/vue-i18n.d.ts. I am not very happy with having to work around this, but for the time being, it's okay.

@dkern
Copy link

dkern commented Aug 7, 2023

@kazupon As this ticket is still on need input and you wanted an example, here you go:
https://stackblitz.com/edit/vitejs-vite-utp7nu?file=src%2FApp.vue

Now, as this is not an issue on the runtime but on type checking, execute the following command in the console to see the actual error:
vue-tsc --noEmit --composite false

You should get this response in console:

src/App.vue:1:14 - error TS2339: Property '$t' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: { key?: string | number | symbol | undefined; ref?: VNodeRef | undefined; ref_for?: boolean | undefined; ... 8 more ...; style?: unknown; }; ... 10 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (arg...'.

1 {{ $t('test') }}
~~

Found 1 error in src/App.vue:1

Copy link
Member

kazupon commented Aug 9, 2023

@dkern
Thank you your reprodution!

Your issue has fixed at v9.3.0, so if you would like to use, you can install v9.3.0-beta.25

@bkis
Copy link

bkis commented Aug 9, 2023

@kazupon
I am on v9.3.0-beta.25 and I get

error TS2339: Property '$t' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: { key?: string | number | symbol | undefined; ref?: VNodeRef | undefined; ref_for?: boolean | undefined; ... 8 more ...; style?: unknown; }; ... 10 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (arg...'

everywhere I use $t in my templates. I have set legacy: false and globalInjection: true. So I still need the workaround I posted above (modified workaround originally coming from @dkern) for it to work.

EDIT: It is fixed with 9.3.0-beta.25, I just had an old version installed 🤦

@dkern
Copy link

dkern commented Aug 9, 2023

Thank you @kazupon. I've tested it in the example on stackbliz and it seems to work. But I'm not allowed to use beta channels in these projects, so I have to wait for the release. Is there any estimated time when 9.3 will be released?

@bkis I can't confirm that. In the example, when I install 9.3.0-beta.25 it doesn't throw any errors. Do you use any other command for type check?

@bkis
Copy link

bkis commented Aug 9, 2023

@kazupon @dkern Sorry for the confusion. I had the dependency set to "vue-i18n": "^9.3.0-beta.25" and npm update didn't update from beta.14 - I have no idea why. Pinning it to 9.3.0-beta.25 (without the caret) and updating actually pulled the correct version. And it is in fact fixed. Thanks!

@DJ-caddev
Copy link

DJ-caddev commented Aug 21, 2023

Someone opened an issue for the BETA 14 issue : #1481

I can confirm that $t works again in BETA 26. Make sure to check package-lock.json to know which version is installed.

EDIT : adding the NPM command:
npm install vue-i18n@^9.3.0-beta.26

@hugorabelo
Copy link

hugorabelo commented Sep 15, 2023

Hi, I'm using version "vue-i18n": "^9.4.1", "vue": "^3.3.4" with Composition API and typescript and having a weird problem here.
I can use this code in template and it works as well

{{ $t('app.sidenav.currentObjectives') }}

but inside the script of the same component I got an error Cannot find name '$t'.ts(2304) and I have to use this code to work and have to do it for each component

import  { useI18n } from 'vue-i18n'
const {t} = useI18n({})

How can I use a global variable $t inside scripts to not import useI18n for each component?

@bkis
Copy link

bkis commented Sep 18, 2023

@hugorabelo I think $t only works in templates. The way you do it seems to be the "official" way to access t() et al. in the script part of a component.

@hugorabelo
Copy link

@bkis Thanks. I already read this document, but my question is: Am I always need to define this const { t } for each component I'm using translation in script?

@dkern
Copy link

dkern commented Sep 19, 2023

@bkis Thanks. I already read this document, but my question is: Am I always need to define this const { t } for each component I'm using translation in script?

Just create yourself a file where you configure your i18n plugin. There you can also do an export of the functions you frequently need to use. For example:

import { createI18n } from 'vue-i18n';

const i18n = createI18n({ ... });
const { t, tm } = i18n.global;

export const $t = t;
export const $tm = tm;

And where ever you need them you can now just import the functions directly, like:

import { $t } from './path/to/file';
$t('translate your message');

But of course, you always need to import them where you want to use it. You could make this variable also globally available in script if you prefer it that way: https://stackoverflow.com/a/65349231/6498658

@bkis
Copy link

bkis commented Sep 19, 2023

Just create yourself a file where you configure your i18n plugin. There you can also do an export of the functions you frequently need to use. For example:

import { createI18n } from 'vue-i18n';

const i18n = createI18n({ ... });
const { t, tm } = i18n.global;

export const $t = t;
export const $tm = tm;

Nice, thanks. Could be a little more concise this way:

export const { t: $t, tm: $tm } = i18n.global;

@hugorabelo
Copy link

Thanks, everyone. I understood the idea. Also, I checked that global properties should be used only in Options API. For composition API, we should import everything. It's working now

@wassim-ben-amor
Copy link

wassim-ben-amor commented Oct 17, 2023

Hello, I am using

    "vue": "^3.3.4",
    "vue-i18n": "9.4.1",

But when using $t in the template, I have a ts error showing:
Property '$t' does not exist on type '{ $: ComponentInternalInstance; ...

I have checked that the installed package is exactly v9.4.1.
Doing a production build or run vite in a dev server compiles correctly without throwing error in the terminal and show correctly the translations.

Do you think I need to define the ComponentCustomProperties interface as mentioned in the answers ?
Is the $t still available in the templates after migrating to v9 ? Because in this doc I see that we have the usage of $t.

Thank you,

@Nick-Hopps
Copy link

Hello, I am using

    "vue": "^3.3.4",
    "vue-i18n": "9.4.1",

But when using $t in the template, I have a ts error showing: Property '$t' does not exist on type '{ $: ComponentInternalInstance; ...

I have checked that the installed package is exactly v9.4.1. Doing a production build or run vite in a dev server compiles correctly without throwing error in the terminal and show correctly the translations.

Do you think I need to define the ComponentCustomProperties interface as mentioned in the answers ? Is the $t still available in the templates after migrating to v9 ? Because in this doc I see that we have the usage of $t.

Thank you,

try to remove old node_moduls and package-lock file and reinstall

@Nick-Hopps
Copy link

Nick-Hopps commented Dec 1, 2023

Because I have a monorepo with vue@3.2.47 installed, and the main version I use is vue@3.3.4. The package '@vue/runtime-core' under the root node_modules belongs to 3.2.47, and 'vue/node_modules' /@vue/runtime-core' is what 3.3.4 actually uses. So the type definition of vue-i18n does not take effect

@ByScripts
Copy link

We're using Yarn Workspace.

Removing all node_modules directories then running yarn install fixed the problem (no need to remove yarn.lock).

@0xDarker
Copy link

0xDarker commented Feb 3, 2024

I'm facing the same issue with vue-i18n@9.9.1 and vue@3.4.15 in pnpm monorepo, $t cannot be recognized.
While I downgrade to vue@3.3.4, it is OK.

@TheNoim
Copy link

TheNoim commented May 15, 2024

I'm facing the same issue with vue-i18n@9.9.1 and vue@3.4.15 in pnpm monorepo, $t cannot be recognized. While I downgrade to vue@3.3.4, it is OK.

Maybe this helps creating a patch:

In dist/vue-i18n.d.ts change the line declare module '@vue/runtime-core' { to declare module 'vue' {.

Like this:

image

This is btw also the way how the vue docs do augmentation: https://vuejs.org/api/utility-types.html#componentcustomproperties I don't know whether there is a reason why it is like this or not.

For the time being I just created a local patch.

@kazupon kazupon added Status: Need More Info Lacks enough info to make progress and removed Status: Need More Info Lacks enough info to make progress labels May 15, 2024
Copy link

Thank you for your feadback!
Would you be able to provide a reproduction 🙏

More info

Why do I need to provide a reproduction?

Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.

What will happen?

If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect.

If Status: Need More Info labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.

How can I create a reproduction?

We have a couple of templates for starting with a minimal reproduction:

👉 Reproduction mininal starter
👉 Reproduction starter with unpluguin-vue-i18n

A public GitHub repository is also perfect. 👌

Please ensure that the reproduction is as minimal as possible.

You might also find these other articles interesting and/or helpful:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Need More Info Lacks enough info to make progress typescript
Projects
None yet
Development

No branches or pull requests