From 60a9b5a693a76ba07049b03c70e81355fca51d52 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Fri, 6 Dec 2024 00:38:09 +0100 Subject: [PATCH] Improve i18n api typing --- .../src/multi-page/i18n.ts | 8 +-- src/login/i18n/withJsx/i18nBuilder.ts | 2 +- test/login/i18n.typelevel-spec.ts | 62 +++++++++++++++++++ 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/bin/initialize-account-theme/src/multi-page/i18n.ts b/src/bin/initialize-account-theme/src/multi-page/i18n.ts index 49062b8c..6dc2d03a 100644 --- a/src/bin/initialize-account-theme/src/multi-page/i18n.ts +++ b/src/bin/initialize-account-theme/src/multi-page/i18n.ts @@ -1,11 +1,9 @@ import { i18nBuilder } from "keycloakify/account"; import type { ThemeName } from "../kc.gen"; -const { useI18n, ofTypeI18n } = i18nBuilder - .withThemeName() - .withExtraLanguages({}) - .withCustomTranslations({}) - .build(); +/** @see: https://docs.keycloakify.dev/i18n */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const { useI18n, ofTypeI18n } = i18nBuilder.withThemeName().build(); type I18n = typeof ofTypeI18n; diff --git a/src/login/i18n/withJsx/i18nBuilder.ts b/src/login/i18n/withJsx/i18nBuilder.ts index 9ec3c873..f3e9ce5f 100644 --- a/src/login/i18n/withJsx/i18nBuilder.ts +++ b/src/login/i18n/withJsx/i18nBuilder.ts @@ -46,7 +46,7 @@ export type I18nBuilder< }> ) => I18nBuilder< ThemeName, - MessageKey_themeDefined, + string extends MessageKey_themeDefined ? never : MessageKey_themeDefined, LanguageTag_notInDefaultSet, ExcludedMethod | "withCustomTranslations" >; diff --git a/test/login/i18n.typelevel-spec.ts b/test/login/i18n.typelevel-spec.ts index bfd0a5d5..af1ebc9a 100644 --- a/test/login/i18n.typelevel-spec.ts +++ b/test/login/i18n.typelevel-spec.ts @@ -62,3 +62,65 @@ type I18n = typeof ofTypeI18n; assert>; } + +{ + const i18n = Reflect(); + + i18n.msg("passwordConfirm"); +} + +{ + const i18n = Reflect(); + + // @ts-expect-error + i18n.msg("iDoNotExist"); +} + +{ + const { ofTypeI18n } = i18nBuilder + .withThemeName<"keycloakify-starter">() + .withCustomTranslations({}) + .build(); + + type I18n = typeof ofTypeI18n; + + { + const i18n = Reflect(); + + // @ts-expect-error + const node = i18n.msg("iDoNotExist"); + + assert>; + } +} + +i18nBuilder.withThemeName<"my-theme-1" | "my-theme-2">().withCustomTranslations({ + en: { + myCustomKey1: "my-custom-key-1-en", + // @ts-expect-error + myCustomKey2: { + "my-theme-1": "my-theme-1-en" + //"my-theme-2": "my-theme-2-en" + } + } +}); + +i18nBuilder + .withThemeName<"my-theme-1" | "my-theme-2">() + .withExtraLanguages({ + he: { + label: "עברית", + getMessages: () => import("./he") + } + }) + .withCustomTranslations({ + en: { + myCustomKey1: "my-custom-key-1-en", + myCustomKey2: "my-custom-key-2-en" + }, + // @ts-expect-error + he: { + myCustomKey1: "my-custom-key-1-he" + //myCustomKey2: "my-custom-key-2-he" + } + });