vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

Typescript allows passing any string as t() argument

Open andresespinosapc opened this issue 1 year ago • 7 comments

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 avatar Aug 09 '22 19:08 andresespinosapc

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

OfekA-IAI avatar Aug 31 '22 05:08 OfekA-IAI

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)

larrifax avatar Sep 08 '22 13:09 larrifax

认为我通过创建自己的可组合包装器来实现此功能,该包装器可返回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

Sweet-KK avatar Oct 28 '22 02:10 Sweet-KK