Created
November 3, 2021 12:47
-
-
Save captain-yossarian/b9d33fe00003e53b1ab41dad7e712237 to your computer and use it in GitHub Desktop.
useTranslation typings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Dict = typeof dict | |
type KeysUnion<T, Cache extends string = ''> = | |
T extends PropertyKey ? Cache : { | |
[P in keyof T]: | |
P extends string | |
? Cache extends '' | |
? KeysUnion<T[P], `${P}`> | |
: Cache | KeysUnion<T[P], `${Cache}.${P}`> | |
: never | |
}[keyof T] | |
type RemoveDot<T extends string> = T extends `.${infer Tail}` ? Tail : T; | |
type ExtractString<T extends string, U extends string, Result extends string = ''> = | |
T extends `${infer Head}${infer Tail}` ? `${Result}${Head}` extends U ? Tail : ExtractString<Tail, U, `${Result}${Head}`> : Result | |
type ValidPrefix<T extends string, U extends string> = T extends `${U}${string}` ? Exclude<T, U> : never | |
type ConcatNamespaceWithPrefix<N extends string, P extends string> = `${N}.${P}` | |
type Values<T> = T[keyof T] | |
type Elem = string; | |
type Acc = Record<string, any> | |
// (acc, elem) => hasProperty(acc, elem) ? acc[elem] : acc | |
type Predicate<Accumulator extends Acc, El extends Elem> = | |
El extends keyof Accumulator ? Accumulator[El] : Accumulator | |
type Reducer< | |
Keys extends Elem, | |
Accumulator extends Acc = {} | |
> = | |
Keys extends `${infer Prop}.${infer Rest}` | |
? Reducer<Rest, Predicate<Accumulator, Prop>> | |
: Keys extends `${infer Last}` | |
? Predicate<Accumulator, Last> | |
: never | |
type UseTranslationsProps<D = typeof dict> = | |
(() => <Prefix extends KeysUnion<D>>(prefix: Prefix) => Reducer<Prefix, D>) | |
& ( | |
< | |
ValidKeys extends KeysUnion<D>, | |
Namespace extends ValidKeys | |
>(namespace?: Namespace) => | |
<Prefix extends RemoveDot<ExtractString<ValidPrefix<KeysUnion<Dict>, Namespace>, Namespace>>>( | |
prefix: Prefix | |
) => Reducer<ConcatNamespaceWithPrefix<Namespace, Prefix>, D> | |
) | |
declare const useTranslations: UseTranslationsProps; | |
const dict = { | |
one: { | |
two: { | |
three: "3", | |
foo: "bar" | |
} | |
}, | |
bar: { | |
baz: 2 | |
} | |
} as const | |
{ | |
const t = useTranslations() // ok | |
const ok = t('one') // {two: ....} | |
} | |
{ | |
const t = useTranslations('one.two') // ok | |
const ok = t('three') // 3 | |
} | |
{ | |
const t = useTranslations() // ok | |
const ok = t('three') // expected error | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment