index.d.ts 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import type { $Subtract, $Tuple } from './helpers.js';
  2. import type {
  3. ReactOptions,
  4. i18n,
  5. Resource,
  6. FlatNamespace,
  7. Namespace,
  8. TypeOptions,
  9. TFunction,
  10. KeyPrefix,
  11. ParseKeys,
  12. TOptions,
  13. } from 'i18next';
  14. import * as React from 'react';
  15. import {
  16. Trans,
  17. TransProps,
  18. TransSelectorProps,
  19. ErrorCode,
  20. ErrorArgs,
  21. } from './TransWithoutContext.js';
  22. export { initReactI18next } from './initReactI18next.js';
  23. export const TransWithoutContext: typeof Trans;
  24. export { Trans, TransProps, TransSelectorProps, ErrorArgs, ErrorCode };
  25. /**
  26. * Content declaration for IcuTrans component
  27. * Describes React components as type + props blueprints that will be rendered
  28. */
  29. export interface IcuTransContentDeclaration {
  30. type: string | React.ComponentType<any>;
  31. props?: {
  32. children?: IcuTransContentDeclaration | IcuTransContentDeclaration[];
  33. [key: string]: any;
  34. };
  35. }
  36. /**
  37. * Props for IcuTransWithoutContext component (no React context)
  38. */
  39. export type IcuTransWithoutContextProps<
  40. Key extends ParseKeys<Ns, TOpt, KPrefix> = string,
  41. Ns extends Namespace = _DefaultNamespace,
  42. KPrefix = undefined,
  43. TContext extends string | undefined = undefined,
  44. TOpt extends TOptions & { context?: TContext } = { context: TContext },
  45. > = {
  46. /** The i18n key to look up the translation */
  47. i18nKey: Key;
  48. /** The default translation in ICU format with numbered tags (e.g., "<0>Click here</0>") */
  49. defaultTranslation: string;
  50. /** Declaration tree describing React components and their props */
  51. content: IcuTransContentDeclaration[];
  52. /** Optional namespace(s) for the translation */
  53. ns?: Ns;
  54. /** Optional values for ICU variable interpolation */
  55. values?: Record<string, any>;
  56. /** i18next instance. If not provided, uses global instance */
  57. i18n?: i18n;
  58. /** Custom translation function */
  59. t?: TFunction<Ns, KPrefix>;
  60. };
  61. /**
  62. * Props for IcuTrans component (with React context support)
  63. */
  64. export type IcuTransProps<
  65. Key extends ParseKeys<Ns, TOpt, KPrefix> = string,
  66. Ns extends Namespace = _DefaultNamespace,
  67. KPrefix = undefined,
  68. TContext extends string | undefined = undefined,
  69. TOpt extends TOptions & { context?: TContext } = { context: TContext },
  70. > = IcuTransWithoutContextProps<Key, Ns, KPrefix, TContext, TOpt>;
  71. /**
  72. * IcuTrans component for rendering ICU MessageFormat translations
  73. * This is the context-aware version that works with I18nextProvider
  74. *
  75. * @example
  76. * ```tsx
  77. * // Type-safe usage with namespace
  78. * <IcuTrans<'welcome.message', 'common'>
  79. * i18nKey="welcome.message"
  80. * defaultTranslation="Welcome <0>friend</0>!"
  81. * content={[{ type: 'strong', props: {} }]}
  82. * />
  83. * ```
  84. */
  85. export interface IcuTransComponent {
  86. <
  87. Key extends ParseKeys<Ns, TOpt, KPrefix> = string,
  88. Ns extends Namespace = _DefaultNamespace,
  89. KPrefix = undefined,
  90. TContext extends string | undefined = undefined,
  91. TOpt extends TOptions & { context?: TContext } = { context: TContext },
  92. >(
  93. props: IcuTransProps<Key, Ns, KPrefix, TContext, TOpt>,
  94. ): React.ReactElement;
  95. }
  96. /**
  97. * IcuTransWithoutContext component for rendering ICU MessageFormat translations
  98. * This version does not use React context and requires explicit i18n instance
  99. *
  100. * @example
  101. * ```tsx
  102. * // Type-safe usage with namespace
  103. * <IcuTransWithoutContext<'welcome.message', 'common'>
  104. * i18nKey="welcome.message"
  105. * defaultTranslation="Welcome <0>back</0>!"
  106. * content={[{ type: 'strong', props: {} }]}
  107. * i18n={i18nInstance}
  108. * />
  109. * ```
  110. */
  111. export interface IcuTransWithoutContextComponent {
  112. <
  113. Key extends ParseKeys<Ns, TOpt, KPrefix> = string,
  114. Ns extends Namespace = _DefaultNamespace,
  115. KPrefix = undefined,
  116. TContext extends string | undefined = undefined,
  117. TOpt extends TOptions & { context?: TContext } = { context: TContext },
  118. >(
  119. props: IcuTransWithoutContextProps<Key, Ns, KPrefix, TContext, TOpt>,
  120. ): React.ReactElement;
  121. }
  122. export const IcuTrans: IcuTransComponent;
  123. export const IcuTransWithoutContext: IcuTransWithoutContextComponent;
  124. export function setDefaults(options: ReactOptions): void;
  125. export function getDefaults(): ReactOptions;
  126. export function setI18n(instance: i18n): void;
  127. export function getI18n(): i18n;
  128. export function composeInitialProps(ForComponent: any): (ctx: unknown) => Promise<any>;
  129. export function getInitialProps(): {
  130. initialI18nStore: {
  131. [ns: string]: {};
  132. };
  133. initialLanguage: string;
  134. };
  135. export interface ReportNamespaces {
  136. addUsedNamespaces(namespaces: Namespace): void;
  137. getUsedNamespaces(): string[];
  138. }
  139. declare module 'i18next' {
  140. // interface i18n {
  141. // reportNamespaces?: ReportNamespaces;
  142. // }
  143. interface CustomInstanceExtensions {
  144. reportNamespaces?: ReportNamespaces;
  145. }
  146. }
  147. type ObjectOrNever = TypeOptions['allowObjectInHTMLChildren'] extends true
  148. ? Record<string, unknown>
  149. : never;
  150. type ReactI18NextChildren = React.ReactNode | ObjectOrNever;
  151. declare module 'react' {
  152. namespace JSX {
  153. interface IntrinsicAttributes {
  154. i18nIsDynamicList?: boolean;
  155. }
  156. }
  157. interface HTMLAttributes<T> {
  158. // This union is inspired by the typings for React.ReactNode. We do this to fix "This JSX tag's 'children' prop
  159. // expects a single child of type 'ReactI18NextChildren', but multiple children were provided":
  160. // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5a1e9f91ed0143adede394adb3f540e650455f71/types/react/index.d.ts#L268
  161. children?: ReactI18NextChildren | Iterable<ReactI18NextChildren>;
  162. }
  163. }
  164. type _DefaultNamespace = TypeOptions['defaultNS'];
  165. export function useSSR(initialI18nStore: Resource, initialLanguage: string): void;
  166. // If the version is earlier than i18next v25.4.0, enableSelector does not exist in TypeOptions, so a conditional type is used to maintain type compatibility.
  167. type _EnableSelector = TypeOptions extends { enableSelector: infer U } ? U : false;
  168. export type UseTranslationOptions<KPrefix> = {
  169. i18n?: i18n;
  170. useSuspense?: boolean;
  171. keyPrefix?: KPrefix;
  172. bindI18n?: string | false;
  173. nsMode?: 'fallback' | 'default';
  174. lng?: string;
  175. // other of these options might also work: https://github.com/i18next/i18next/blob/master/index.d.ts#L127
  176. };
  177. export type UseTranslationResponse<Ns extends Namespace, KPrefix> = [
  178. t: TFunction<Ns, KPrefix>,
  179. i18n: i18n,
  180. ready: boolean,
  181. ] & {
  182. t: TFunction<Ns, KPrefix>;
  183. i18n: i18n;
  184. ready: boolean;
  185. };
  186. // Workaround to make code completion to work when suggesting namespaces.
  187. // This is a typescript limitation when using generics with default values,
  188. // it'll be addressed in this issue: https://github.com/microsoft/TypeScript/issues/52516
  189. export type FallbackNs<Ns> = Ns extends undefined
  190. ? _DefaultNamespace
  191. : Ns extends Namespace
  192. ? Ns
  193. : _DefaultNamespace;
  194. export const useTranslation: _EnableSelector extends true | 'optimize'
  195. ? UseTranslationSelector
  196. : UseTranslationLegacy;
  197. interface UseTranslationLegacy {
  198. <
  199. const Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  200. const KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
  201. >(
  202. ns?: Ns,
  203. options?: UseTranslationOptions<KPrefix>,
  204. ): UseTranslationResponse<FallbackNs<Ns>, KPrefix>;
  205. }
  206. interface UseTranslationSelector {
  207. <
  208. const Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  209. const KPrefix = undefined,
  210. >(
  211. ns?: Ns,
  212. options?: UseTranslationOptions<KPrefix>,
  213. ): UseTranslationResponse<FallbackNs<Ns>, KPrefix>;
  214. }
  215. // Need to see usage to improve this
  216. export function withSSR(): <Props>(WrappedComponent: React.ComponentType<Props>) => {
  217. ({
  218. initialI18nStore,
  219. initialLanguage,
  220. ...rest
  221. }: {
  222. initialI18nStore: Resource;
  223. initialLanguage: string;
  224. } & Props): React.FunctionComponentElement<Props>;
  225. getInitialProps: (ctx: unknown) => Promise<any>;
  226. };
  227. export interface WithTranslation<
  228. Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  229. KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
  230. > {
  231. t: TFunction<FallbackNs<Ns>, KPrefix>;
  232. i18n: i18n;
  233. tReady: boolean;
  234. }
  235. export interface WithTranslationProps {
  236. i18n?: i18n;
  237. useSuspense?: boolean;
  238. }
  239. export function withTranslation<
  240. Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  241. KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
  242. >(
  243. ns?: Ns,
  244. options?: {
  245. withRef?: boolean;
  246. keyPrefix?: KPrefix;
  247. },
  248. ): <
  249. C extends React.ComponentType<React.ComponentProps<any> & WithTranslationProps>,
  250. ResolvedProps = React.JSX.LibraryManagedAttributes<
  251. C,
  252. $Subtract<React.ComponentProps<C>, WithTranslationProps>
  253. >,
  254. >(
  255. component: C,
  256. ) => React.ComponentType<Omit<ResolvedProps, keyof WithTranslation<Ns>> & WithTranslationProps>;
  257. export interface I18nextProviderProps {
  258. children?: React.ReactNode;
  259. i18n: i18n;
  260. defaultNS?: string | string[];
  261. }
  262. export const I18nextProvider: React.FunctionComponent<I18nextProviderProps>;
  263. export const I18nContext: React.Context<{ i18n: i18n }>;
  264. export interface TranslationProps<
  265. Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  266. KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
  267. > {
  268. children: (
  269. t: TFunction<FallbackNs<Ns>, KPrefix>,
  270. options: {
  271. i18n: i18n;
  272. lng: string;
  273. },
  274. ready: boolean,
  275. ) => React.ReactNode;
  276. ns?: Ns;
  277. i18n?: i18n;
  278. useSuspense?: boolean;
  279. keyPrefix?: KPrefix;
  280. nsMode?: 'fallback' | 'default';
  281. }
  282. export function Translation<
  283. Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,
  284. KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
  285. >(props: TranslationProps<Ns, KPrefix>): any;