mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 05:51:56 +08:00
Improve: i18n type gymnastics (#116)
Co-authored-by: Dreamacro <8615343+Dreamacro@users.noreply.github.com>
This commit is contained in:
parent
a29c1121f1
commit
c298eae5bb
@ -1,3 +1,7 @@
|
||||
import { IsEqual } from 'type-fest'
|
||||
|
||||
import Infer from '@lib/type'
|
||||
|
||||
import en_US from './en_US'
|
||||
import zh_CN from './zh_CN'
|
||||
|
||||
@ -8,6 +12,16 @@ export const Language = {
|
||||
|
||||
export type Lang = keyof typeof Language
|
||||
|
||||
type US = typeof Language.en_US
|
||||
type CN = typeof Language.zh_CN
|
||||
|
||||
// type guard for US and CN
|
||||
type TrueGuard<T extends true> = T
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type _equalGuard = TrueGuard<IsEqual<Infer<US>, Infer<CN>>>
|
||||
|
||||
export type LocalizedType = US
|
||||
|
||||
export const locales = Object.keys(Language)
|
||||
|
||||
export function getDefaultLanguage (): Lang {
|
||||
|
5
src/lib/type.ts
Normal file
5
src/lib/type.ts
Normal file
@ -0,0 +1,5 @@
|
||||
type InferRecursion<K extends string, T> = T extends object ? { [P in keyof T]: P extends string ? InferRecursion<`${K}.${P}`, T[P]> : K }[keyof T] : K
|
||||
|
||||
type Infer<T> = Extract<{ [K in keyof T]: K extends string ? InferRecursion<K, T[K]> : unknown }[keyof T], string>
|
||||
|
||||
export default Infer
|
@ -10,13 +10,14 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { Get } from 'type-fest'
|
||||
|
||||
import { Language, locales, Lang, getDefaultLanguage } from '@i18n'
|
||||
import { Language, locales, Lang, getDefaultLanguage, LocalizedType } from '@i18n'
|
||||
import { partition } from '@lib/helper'
|
||||
import { useWarpImmerSetter, WritableDraft } from '@lib/jotai'
|
||||
import { isClashX, jsBridge } from '@lib/jsBridge'
|
||||
import { Snapshot } from '@lib/request'
|
||||
import * as API from '@lib/request'
|
||||
import { StreamReader } from '@lib/streamer'
|
||||
import Infer from '@lib/type'
|
||||
import * as Models from '@models'
|
||||
import { Log } from '@models/Log'
|
||||
|
||||
@ -31,9 +32,9 @@ export function useI18n () {
|
||||
const lang = useMemo(() => defaultLang ?? getDefaultLanguage(), [defaultLang])
|
||||
|
||||
const translation = useCallback(
|
||||
function <Namespace extends keyof typeof Language['en_US']>(namespace: Namespace) {
|
||||
function t<Path extends string> (path: Path) {
|
||||
return get(Language[lang][namespace], path) as unknown as Get<typeof Language['en_US'][Namespace], Path>
|
||||
function <Namespace extends keyof LocalizedType>(namespace: Namespace) {
|
||||
function t<Path extends Infer<LocalizedType[Namespace]>> (path: Path) {
|
||||
return get(Language[lang][namespace], path) as unknown as Get<LocalizedType[Namespace], Path>
|
||||
}
|
||||
return { t }
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user