Skip to content

Instantly share code, notes, and snippets.

@u840903
Created October 20, 2023 17:15
Show Gist options
  • Save u840903/6bef01ac10cad647f54cfd6afc44ee66 to your computer and use it in GitHub Desktop.
Save u840903/6bef01ac10cad647f54cfd6afc44ee66 to your computer and use it in GitHub Desktop.
const CommonTranslations = {
COMMON_SUBMIT: "SUBMIT",
COMMON_WELCOME: "WELCOME {{username}}",
} as const;
const StartPageTranslations = {
START_PAGE_TITLE: "Startpage",
START_PAGE_ERROR: "Error: {{error}}",
} as const;
type GetParamKeys<TTranslation extends string> = TTranslation extends ""
? []
: TTranslation extends `${string}{{${infer Param}}}${infer Tail}`
? [Param, ...GetParamKeys<Tail>]
: [];
const constTranslate = <
TTranslations extends Record<string, string>,
TKey extends keyof TTranslations,
TParamKeys extends string[] = GetParamKeys<TTranslations[TKey]>,
>(
translations: TTranslations,
key: TKey,
...args: TParamKeys extends []
? []
: [params: Record<TParamKeys[number], string>]
) => {
const translation = translations[key];
const params: any = args[0] || {};
return translation.replace(/{(\w+)}/g, (_, key) => params[key]);
};
const typeTranslate = <
T extends Record<string, string>,
TParamKeys extends string[] = GetParamKeys<T[keyof T]>,
>(
key: keyof T,
...args: TParamKeys extends []
? []
: [params: Record<TParamKeys[number], string>]
) => {
console.log(key, args);
};
// This works as it should.
constTranslate(CommonTranslations, "COMMON_WELCOME", { username: "Jan" });
// This works as it should.
constTranslate(StartPageTranslations, "START_PAGE_TITLE");
// This errors as it should.
constTranslate(CommonTranslations, "COMMON_WELCOME");
// This should give an error, but doesn't.
typeTranslate<typeof CommonTranslations>("COMMON_WELCOME");
// This works as it should.
typeTranslate<typeof StartPageTranslations>("START_PAGE_TITLE");
// This works as it should.
typeTranslate<typeof CommonTranslations>("COMMON_WELCOME", { username: "Jan" });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment