SkateSpots/src/i18n/deepMerge.ts
SkateSpots 9a5b706b1a i18n: close the drift — all 20 locales back to 100%
245 keys had accumulated in en/es only (trustUi, labOptions, cordnUi, socialUi,
walletUi, marketTerms, …), leaving every other locale at 97%. Backfilled 245x20 =
4,900 strings into src/i18n/<lang>/drift.ts and merged them through a new shared
src/i18n/deepMerge.ts — a shallow ...drift spread would clobber existing
namespaces, so index.ts deep-merges instead. Verified: check-i18n all 20 at 100%,
tsc + eslint clean.
2026-10-13 19:14:17 +07:00

23 lines
889 B
TypeScript

type TranslationDict = { [key: string]: string | TranslationDict };
/**
* Recursively merge `extra` into `base`, so a partial fragment ADDS keys into
* existing namespaces instead of replacing them. A shallow spread would clobber a
* whole namespace (e.g. `...drift` last would drop every other `socialUi` key).
* Plain nested string dictionaries only.
*/
export function deepMerge<T extends TranslationDict>(base: T, extra: TranslationDict): T {
const out: TranslationDict = { ...base };
for (const [key, value] of Object.entries(extra)) {
const current = out[key];
if (
value && typeof value === 'object' && !Array.isArray(value) &&
current && typeof current === 'object' && !Array.isArray(current)
) {
out[key] = deepMerge(current as TranslationDict, value as TranslationDict);
} else {
out[key] = value;
}
}
return out as T;
}