Skip to content

Commit 5efaf0c

Browse files
committed
Enable interpolation in translation function #25
1 parent 9e92b6f commit 5efaf0c

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

src/lib/i18n.tsx

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,44 @@ function getLanguageBestApprox<Language extends string>(params: {
6262
return undefined;
6363
}
6464

65+
type FrMessagesToTranslationFunction<
66+
FrMessages extends Record<string, string | ((params: any) => string)>
67+
> = {
68+
(messageKey: NonFunctionMessageKey<FrMessages>): string;
69+
<K extends FunctionMessageKey<FrMessages>>(
70+
messageKey: K,
71+
params: ExtractArgument<FrMessages[K]>
72+
): string;
73+
};
74+
75+
type ExtractArgument<Message extends string | ((params: any) => string)> = Message extends (
76+
params: any
77+
) => string
78+
? Parameters<Message>[0]
79+
: never;
80+
81+
type NonFunctionMessageKey<FrMessages extends Record<string, string | ((params: any) => string)>> =
82+
{
83+
[Key in keyof FrMessages]: FrMessages[Key] extends string ? Key : never;
84+
}[keyof FrMessages];
85+
86+
type FunctionMessageKey<FrMessages extends Record<string, string | ((params: any) => string)>> =
87+
Exclude<keyof FrMessages, NonFunctionMessageKey<FrMessages>>;
88+
89+
type X = NonFunctionMessageKey<{ foo: string; bar: (params: { x: number }) => string }>;
90+
type Y = FunctionMessageKey<{ foo: string; bar: (params: { x: number }) => string }>;
91+
6592
export function createComponentI18nApi<
6693
ComponentName extends string,
67-
FrMessages extends Record<string, string>
94+
FrMessages extends Record<string, string | ((params: any) => string)>
6895
>(params: {
6996
componentName: ComponentName;
7097
frMessages: FrMessages;
7198
}): {
72-
useTranslation: () => { t: (messageKey: keyof FrMessages) => string };
99+
useTranslation: () => { t: FrMessagesToTranslationFunction<FrMessages> };
73100
} & Record<
74101
`add${ComponentName}Translations`,
75-
(params: { lang: string; messages: Partial<Record<keyof FrMessages, string>> }) => void
102+
(params: { lang: string; messages: FrMessages }) => void
76103
> {
77104
const { componentName, frMessages } = params;
78105

@@ -94,11 +121,12 @@ export function createComponentI18nApi<
94121
return bestApproxLang ?? "fr";
95122
}, [lang]);
96123

97-
function t(messageKey: keyof FrMessages): string {
98-
return (
124+
function t(messageKey: keyof FrMessages, params?: any): string {
125+
const messageOrFn =
99126
(messagesByLang as any)[bestMatchLang][messageKey] ??
100-
(messagesByLang["fr"] as any)[messageKey]
101-
);
127+
(messagesByLang["fr"] as any)[messageKey];
128+
129+
return params === undefined ? messageOrFn : messageOrFn(params);
102130
}
103131

104132
return { t };

0 commit comments

Comments
 (0)