From f1524192f39b00610f135b33d1663bc089c759a6 Mon Sep 17 00:00:00 2001 From: Aral Roca Gomez Date: Mon, 17 Jul 2023 20:02:43 +0200 Subject: [PATCH] feat: add Paths type for type safety (#1108) * feat: add Paths type for type safety * fix to satisfy the constraint 'string' --- .../with-app-directory/next-translate.d.ts | 23 ++++++++ src/index.tsx | 53 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 examples/with-app-directory/next-translate.d.ts diff --git a/examples/with-app-directory/next-translate.d.ts b/examples/with-app-directory/next-translate.d.ts new file mode 100644 index 0000000..ea3fac6 --- /dev/null +++ b/examples/with-app-directory/next-translate.d.ts @@ -0,0 +1,23 @@ +import type { Paths, I18n, Translate } from 'next-translate' + +export interface TranslationsKeys { + common: Paths + home: Paths +} + +export interface TypeSafeTranslate + extends Omit { + t: { + ( + key: TranslationsKeys[Namespace], + ...rest: Tail> + ): string + (template: TemplateStringsArray): string + } +} + +declare module 'next-translate/useTranslation' { + export default function useTranslation< + Namespace extends keyof TranslationsKeys + >(namespace: Namespace): TypeSafeTranslate +} diff --git a/src/index.tsx b/src/index.tsx index 407ff6f..d1dc7eb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -143,6 +143,59 @@ declare global { } } +//////// For type safety (next-translate.d.ts): /////////// +/* + * + * import type { Paths, I18n, Translate } from "next-translate"; + * + * export interface TranslationsKeys { + * common: Paths; + * home: Paths; + * } + * + * export interface TypeSafeTranslate + * extends Omit { + * t: { + * (key: TranslationsKeys[Namespace], ...rest: Tail>): string; + * (template: TemplateStringsArray): string; + * }; + * } + * + * declare module "next-translate/useTranslation" { + * export default function useTranslation< + * Namespace extends keyof TranslationsKeys, + * >(namespace: Namespace): TypeSafeTranslate; + * } + */ + +type RemovePlural = Key extends `${infer Prefix}${ + | '_zero' + | '_one' + | '_two' + | '_few' + | '_many' + | '_other' + | `_${infer Num}`}` + ? Prefix + : Key + +type Join = S1 extends string + ? S2 extends string + ? `${S1}.${S2}` + : never + : never + +// @ts-ignore +export type Paths = RemovePlural< + // @ts-ignore + { + // @ts-ignore + [K in Extract]: T[K] extends Record + ? Join> + : K + }[Extract] +> + // TODO: Remove this in future versions > 2.0.0 function nextTranslate(nextConfig: NextConfig = {}): NextConfig { console.log(`