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!
