type for namespace

This commit is contained in:
Stephen Zhou 2025-12-25 19:45:26 +08:00
parent fcd25d3d45
commit 3736e2d91e
No known key found for this signature in database
2 changed files with 11 additions and 15 deletions

View File

@ -69,10 +69,6 @@ export const namespaces = {
workflow, workflow,
} }
export type Namespaces = typeof namespaces
// pluginTrigger -> plugin-trigger
export type KebabCase<S extends string> = S extends `${infer T}${infer U}` export type KebabCase<S extends string> = S extends `${infer T}${infer U}`
? T extends Lowercase<T> ? T extends Lowercase<T>
? `${T}${KebabCase<U>}` ? `${T}${KebabCase<U>}`
@ -83,10 +79,10 @@ export type CamelCase<S extends string> = S extends `${infer T}-${infer U}`
? `${T}${Capitalize<CamelCase<U>>}` ? `${T}${Capitalize<CamelCase<U>>}`
: S : S
export type KeyPrefix = keyof typeof namespaces export type NamespaceCamelCase = keyof typeof namespaces
export type Namespace = KebabCase<KeyPrefix> export type NamespaceKebabCase = KebabCase<NamespaceCamelCase>
const requireSilent = async (lang: Locale, namespace: Namespace) => { const requireSilent = async (lang: Locale, namespace: NamespaceKebabCase) => {
let res let res
try { try {
res = (await import(`../i18n/${lang}/${namespace}.json`)).default res = (await import(`../i18n/${lang}/${namespace}.json`)).default
@ -98,11 +94,11 @@ const requireSilent = async (lang: Locale, namespace: Namespace) => {
return res return res
} }
const NAMESPACES = Object.keys(namespaces).map(kebabCase) as Namespace[] const NAMESPACES = Object.keys(namespaces).map(kebabCase) as NamespaceKebabCase[]
// Load a single namespace for a language // Load a single namespace for a language
export const loadNamespace = async (lang: Locale, ns: Namespace) => { export const loadNamespace = async (lang: Locale, ns: NamespaceKebabCase) => {
const camelNs = camelCase(ns) as KeyPrefix const camelNs = camelCase(ns) as NamespaceCamelCase
if (i18n.hasResourceBundle(lang, camelNs)) if (i18n.hasResourceBundle(lang, camelNs))
return return

View File

@ -1,5 +1,5 @@
import type { Locale } from '.' import type { Locale } from '.'
import type { KeyPrefix, Namespace } from './i18next-config' import type { NamespaceCamelCase, NamespaceKebabCase } from './i18next-config'
import { match } from '@formatjs/intl-localematcher' import { match } from '@formatjs/intl-localematcher'
import { camelCase } from 'es-toolkit/compat' import { camelCase } from 'es-toolkit/compat'
import { createInstance } from 'i18next' import { createInstance } from 'i18next'
@ -10,11 +10,11 @@ import { initReactI18next } from 'react-i18next/initReactI18next'
import { i18n } from '.' import { i18n } from '.'
// https://locize.com/blog/next-13-app-dir-i18n/ // https://locize.com/blog/next-13-app-dir-i18n/
const initI18next = async (lng: Locale, ns: Namespace) => { const initI18next = async (lng: Locale, ns: NamespaceKebabCase) => {
const i18nInstance = createInstance() const i18nInstance = createInstance()
await i18nInstance await i18nInstance
.use(initReactI18next) .use(initReactI18next)
.use(resourcesToBackend((language: Locale, namespace: string) => { .use(resourcesToBackend((language: Locale, namespace: NamespaceKebabCase) => {
return import(`../i18n/${language}/${namespace}.json`) return import(`../i18n/${language}/${namespace}.json`)
})) }))
.init({ .init({
@ -26,8 +26,8 @@ const initI18next = async (lng: Locale, ns: Namespace) => {
return i18nInstance return i18nInstance
} }
export async function getTranslation(lng: Locale, ns: Namespace) { export async function getTranslation(lng: Locale, ns: NamespaceKebabCase) {
const camelNs = camelCase(ns) as KeyPrefix const camelNs = camelCase(ns) as NamespaceCamelCase
const i18nextInstance = await initI18next(lng, ns) const i18nextInstance = await initI18next(lng, ns)
return { return {
t: i18nextInstance.getFixedT(lng, camelNs), t: i18nextInstance.getFixedT(lng, camelNs),