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

Typescript allows passing any string as t() argument #1116

Open
3 tasks done
andresespinosapc opened this issue Aug 9, 2022 · 7 comments
Open
3 tasks done

Typescript allows passing any string as t() argument #1116

andresespinosapc opened this issue Aug 9, 2022 · 7 comments
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf Status: Proposal Request for comments typescript

Comments

@andresespinosapc
Copy link

Clear and concise description of the problem

I followed all the steps from the Typescript support page but it does not give an error when I use the t function with a missing key.

It does show autocomplete suggestions in the template though.

Suggested solution

Typescript should give an error when trying to use a key that is not in the schema

Alternative

No response

Additional context

No response

Validations

@andresespinosapc andresespinosapc added the Status: Proposal Request for comments label Aug 9, 2022
@OfekA-IAI
Copy link

Any chance this is planned? Has anyone attempted adding this to their project somehow?

@larrifax
Copy link

larrifax commented Sep 8, 2022

Think I got this working by creating my own wrapper composable returning a t() function with custom types:

type Translations = Messages["en"];

type PathToLeaves<T, Cache extends string = ""> = T extends PropertyKey
  ? Cache
  : {
      [P in keyof T]: P extends string
        ? Cache extends ""
          ? PathToLeaves<T[P], `${P}`>
          : PathToLeaves<T[P], `${Cache}.${P}`>
        : never;
    }[keyof T];

type TranslationPaths = PathToLeaves<Translations>;

export const useTranslation = () => {
  const { t } = useI18n<{ messages: Messages }>();

  return { t: (path: TranslationPaths, named?: NamedValue) => (named ? t(path, named) : t(path)) } as const;
};

It's using some dark-magic Typescript tricks that I got from https://stackoverflow.com/a/69881190/852765 (adjusted it a little bit to fit my use-case)

@Sweet-KK
Copy link

认为我通过创建自己的可组合包装器来实现此功能,该包装器可返回t()具有自定义类型的函数:

type Translations = Messages["en"];

type PathToLeaves<T, Cache extends string = ""> = T extends PropertyKey
  ? Cache
  : {
      [P in keyof T]: P extends string
        ? Cache extends ""
          ? PathToLeaves<T[P], `${P}`>
          : PathToLeaves<T[P], `${Cache}.${P}`>
        : never;
    }[keyof T];

type TranslationPaths = PathToLeaves<Translations>;

export const useTranslation = () => {
  const { t } = useI18n<{ messages: Messages }>();

  return { t: (path: TranslationPaths, named?: NamedValue) => (named ? t(path, named) : t(path)) } as const;
};

它使用了我从https://stackoverflow.com/a/69881190/852765获得的一些黑暗魔法 Typescript 技巧(稍微调整一下以适合我的用例)

How can I do to show the key corresponding to the value then typing?
image

@kazupon kazupon added Type: Improvement Includes backwards-compatible fixes ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf typescript and removed Type: Improvement Includes backwards-compatible fixes labels Nov 15, 2022 — with Volta.net
@Vissie2
Copy link

Vissie2 commented Feb 16, 2023

Even though the workaround from @larrifax is somewhat helpful. I'm having a difficult time taking into account all overloads of t() to make usage possible for all parameters. Especially because we can't just make a type of the function overloads due to a design limitation of TypeScript (microsoft/TypeScript#32164).

This is also a problem for other translation functions like tm() and rt().

@OfekA-IAI
Copy link

Even though the workaround from @larrifax is somewhat helpful. I'm having a difficult time taking into account all overloads of t() to make usage possible for all parameters. Especially because we can't just make a type of the function overloads due to a design limitation of TypeScript (microsoft/TypeScript#32164).

This is also a problem for other translation functions like tm() and rt().

Agree, it's working but a pain to do and configure. This should be built in 🙏🙂

ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 10, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

The rest of them are waiting for PRs at Vuetify's side and an SDK upgrade
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 10, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 12, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 12, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 12, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 12, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
ferferga added a commit to jellyfin/jellyfin-vue that referenced this issue Apr 13, 2023
Locales are fully typed now. Keep track of intlify/vue-i18n#1116 for better TS support for them

- The rest of them are waiting for PRs at Vuetify's side, an SDK upgrade and a further investigation of our typed routes setup.
- Deep type instantiation is also fixed.
@isbosykh
Copy link

Any updates?

@danwithabox
Copy link

I too would like this feature!
I made my own useI18nStrict() composable that returns a stricter t() not unlike @larrifax's, but then I realized tm() would be a lot more hassle because of the return type.
A fully signature-compatible useI18nStrict() as a drop-in replacement is about the best we could do besides official support, but mimicking the entire surface area of useI18n() seems painful 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf Status: Proposal Request for comments typescript
Projects
None yet
Development

No branches or pull requests

8 participants