typescript - String som returtype fra t()-funksjonen med i18next


Med i18next v22.0.0 kom full typesikkerhet for oversettelsesfunksjonen t('world.greeting'), noe som er flott. Men siden du kan bruke t()-funksjonen for å hente objekter fra nestede oversettelser, kan den returnere et objekt eller en streng.

Jeg sender alltid oversettelsesnøkler som resulterer i strenger. Jeg bruker hovedsakelig t() i en kontekst der det må returnere en streng, så en funksjon som i følgende kodebit gir en TypeScript-feil:

const resources = {
  en: {
    translation: {
      world:  {
        withGreeting: 'Hello World',
        withoutGreeting: 'World',
        someNestedProperty: {
          hello: 'Text',
        }
      },
    },
  },
}

// Declare i18next typings: https://www.i18next.com/overview/typescript
declare module "i18next" {
  interface CustomTypeOptions {
    resources: typeof resources["en"];
  }
}


// (...) initialize i18next

const getText = (enabled: boolean): string => {
   if(enabled) {
     // Typescript Error: string | { hello: string } not assignable to type string
     return t('world.withGreeting');  
   }
   return t('world.withoutGreeting');
}

Er det mulig med litt TypeScript-magisk slik at du tvinger t() til bare å returnere en streng?

Svar #1

Det har gått lang tid, men i tilfelle noen kommer over dette, klarte jeg å overskrive den opprinnelige TFunction-grensesnittet i i18next.

Jeg opprettet en fil med samme navn som den med TFuncion-grensesnittdeklarasjonen i node_modules (index.d.ts). Jeg kopierte deretter det originale TFuncion-grensesnittet, men erstattet alle returtypene med string.

Den siste index.d.ts-filen hadde dette innholdet:

declare module 'i18next' {

  export interface TFunction {
    // basic usage
    <
      TResult extends TFunctionResult = string,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
    ): string
    <
      TResult extends TFunctionResult = TFunctionDetailedResult<object>,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
      options?: TOptions<TInterpolationMap> & { returnDetails: true; returnObjects: true },
    ): string
    <
      TResult extends TFunctionResult = TFunctionDetailedResult,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
      options?: TOptions<TInterpolationMap> & { returnDetails: true },
    ): string
    <
      TResult extends TFunctionResult = object,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
      options?: TOptions<TInterpolationMap> & { returnObjects: true },
    ): string
    <
      TResult extends TFunctionResult = string,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
      options?: TOptions<TInterpolationMap> | string,
    ): string
    // overloaded usage
    <
      TResult extends TFunctionResult = string,
      TKeys extends TFunctionKeys = string,
      TInterpolationMap extends object = StringMap,
    >(
      key: TKeys | TKeys[],
      defaultValue?: string,
      options?: TOptions<TInterpolationMap> | string,
    ): string
  }
}

Jeg plasserte filen i en mappe kalt overrides og det fungerte for meg!

Relaterte artikler