feat: move i18n type utils to lib and describe (#33)
This commit is contained in:
parent
d15d761f1a
commit
f67abf5e46
1
src/lib/index.ts
Normal file
1
src/lib/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './types';
|
33
src/lib/types.ts
Normal file
33
src/lib/types.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* @example type Output = Split<'a.b1' | 'a.b2', '.'>;
|
||||||
|
* // ["a", "b1"] | ["a", "b2"]
|
||||||
|
*/
|
||||||
|
type Split<S extends string, D extends string> =
|
||||||
|
S extends `${infer A}${D}${infer B}` ? [A, ...Split<B, D>] : [S];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @example type Output = NestedObject<["a", "b1"] | ["a", "b2"]>;
|
||||||
|
* // { a: { b1: string; }; } | { a: { b2: string; }; }
|
||||||
|
*/
|
||||||
|
type NestedObject<T extends string[]> =
|
||||||
|
T extends [infer Head, ...infer Tail] ?
|
||||||
|
Head extends string ?
|
||||||
|
{ [key in Head]: NestedObject<Tail extends string[] ? Tail : []> } : never :
|
||||||
|
string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @example type Output = UnionToIntersection<{ a: { b1: string; }; } | { a: { b2: string; }; }>;
|
||||||
|
* // { a: { b1: string; }; } & { a: { b2: string; }; }
|
||||||
|
*/
|
||||||
|
type UnionToIntersection<U> =
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @example type Output = CreateTree<'a.b1' | 'a.b2', '.'>;
|
||||||
|
* // { a: { b1: string; }; } & { a: { b2: string; }; }
|
||||||
|
*/
|
||||||
|
export type CreateTree<T> =
|
||||||
|
UnionToIntersection<T extends infer U ?
|
||||||
|
U extends string ?
|
||||||
|
NestedObject<Split<U, '.'>> : never : never>;
|
23
src/models/i18next.d.ts
vendored
23
src/models/i18next.d.ts
vendored
@ -1,24 +1,5 @@
|
|||||||
import defaultLocale from '../../locales/ru.json';
|
import defaultLocale from '../../locales/ru.json';
|
||||||
|
import { CreateTree } from '../lib';
|
||||||
type Split<S extends string, D extends string> =
|
|
||||||
S extends `${infer A}${D}${infer B}` ? [A, ...Split<B, D>] : [S];
|
|
||||||
|
|
||||||
type NestedObject<T extends string[]> =
|
|
||||||
T extends [infer Head, ...infer Tail] ?
|
|
||||||
Head extends string ?
|
|
||||||
{ [key in Head]: NestedObject<Tail extends string[] ? Tail : []> } : never :
|
|
||||||
string;
|
|
||||||
|
|
||||||
// Основная утилита для обработки union type
|
|
||||||
type CreateTree<T> =
|
|
||||||
UnionToIntersection<T extends infer U ?
|
|
||||||
U extends string ?
|
|
||||||
NestedObject<Split<U, '.'>> : never : never>;
|
|
||||||
|
|
||||||
// Утилита для объединения типов
|
|
||||||
type UnionToIntersection<U> =
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
||||||
|
|
||||||
type LanguageResource = CreateTree<keyof typeof defaultLocale>;
|
type LanguageResource = CreateTree<keyof typeof defaultLocale>;
|
||||||
|
|
||||||
@ -26,6 +7,6 @@ declare module "i18next" {
|
|||||||
interface CustomTypeOptions {
|
interface CustomTypeOptions {
|
||||||
resources: {
|
resources: {
|
||||||
'~': LanguageResource
|
'~': LanguageResource
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user