Skip to content

Commit

Permalink
Add type support to plurals (#1399)
Browse files Browse the repository at this point in the history
* Add support to plurals

* Add plurals namespace
  • Loading branch information
pedrodurek authored Nov 9, 2021
1 parent f3612c5 commit e3c6c06
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
7 changes: 7 additions & 0 deletions test/typescript/custom-types/custom-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ declare module 'react-i18next' {
barfoo: 'barfoo';
};
};
plurals: {
foo_zero: 'foo';
foo_one: 'foo';
foo_two: 'foo';
foo_many: 'foo';
foo_other: 'foo';
};
};
}
}
10 changes: 10 additions & 0 deletions test/typescript/custom-types/useTranslation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ function keyPrefixOption() {
return <>{t('barfoo')}</>;
}

function jsonFormatV4Plurals() {
const [t] = useTranslation('plurals');
return (
<>
{t('foo')}
{t('foo_one')}
</>
);
}

function expectErrorWhenNamespaceDoesNotExist() {
// @ts-expect-error
const [t] = useTranslation('fake');
Expand Down
19 changes: 14 additions & 5 deletions ts4.1/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ export interface Resources {}
* declare module 'react-i18next' {
* interface CustomTypeOptions {
* defaultNS: 'custom';
* returnNull: false,
* returnEmptyString: false,
* returnNull: false;
* returnEmptyString: false;
* keySeparator: '.';
* jsonFormat: 'v4';
* resources: {
* custom: {
* foo: 'foo';
Expand All @@ -56,6 +58,7 @@ type TypeOptions = MergeBy<
returnEmptyString: true;
keySeparator: '.';
defaultNS: 'translation';
jsonFormat: 'v4';
resources: Resources;
},
CustomTypeOptions
Expand Down Expand Up @@ -92,6 +95,12 @@ declare module 'i18next' {
}
}

type WithOrWithoutPlural<K> = TypeOptions['jsonFormat'] extends 'v4'
? K extends `${infer B}_${'zero' | 'one' | 'two' | 'few' | 'many' | 'other'}`
? B | K
: K
: K;

// Normalize single namespace
type AppendKeys<K1, K2, S extends string = TypeOptions['keySeparator']> = `${K1 & string}${S}${K2 &
string}`;
Expand All @@ -100,11 +109,11 @@ type AppendKeys2<K1, K2, S extends string = TypeOptions['keySeparator']> = `${K1
type Normalize2<T, K = keyof T> = K extends keyof T
? T[K] extends Record<string, any>
? T[K] extends readonly any[]
? AppendKeys2<K, keyof T[K]> | AppendKeys2<K, Normalize2<T[K]>>
: AppendKeys<K, keyof T[K]> | AppendKeys<K, Normalize2<T[K]>>
? AppendKeys2<K, WithOrWithoutPlural<keyof T[K]>> | AppendKeys2<K, Normalize2<T[K]>>
: AppendKeys<K, WithOrWithoutPlural<keyof T[K]>> | AppendKeys<K, Normalize2<T[K]>>
: never
: never;
type Normalize<T> = keyof T | Normalize2<T>;
type Normalize<T> = WithOrWithoutPlural<keyof T> | Normalize2<T>;

// Normalize multiple namespaces
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
Expand Down

0 comments on commit e3c6c06

Please sign in to comment.