Utilizar i18n de una forma más eficiente (versión TS)
Cuando hablamos de i18n en una aplicación nos solemos referir a la funcionalidad o soporte de internacionalización de la misma.
En JavaScript contamos con una serie de librerías que nos ayudan a dar soporte a esta funcionalidad y sin ir más lejos, existe una muy conocida llamada i18n-next, que además tiene soporte en los frameworks más conocidos y está altamente extendida.
Cuando la instalamos en nuestros proyectos la solemos usar con literales de traducción como cadenas de texto, y si bien, es una forma rápida de obtener la traducción, esta alternativa es deficiente de cara a su manipulación y refactorización, además de convertirla en un coladero de errores:
// has a mistake 👻
t("comon.cancel")
Probablemente he llamado a la traducción como "common.cancel" y sin embargo al usarla he puesto "comon.cancel"
Solución con TypeScript
Hoy te propongo crear una función que te permitirá usar la librería de una forma distinta, la cual te ayudará a refactorizar esas traducciones sin problemas y que no te equivoques al escribirla. Por fin di adiós al típico error de contineu
cuando querías poner continue
.
Vamos a escribir una función recursiva que será la encargada de devolvernos la cadena que espera i18n
como un string, pero que nos permitirá usarla como un objeto:
export const extractObjectPath = <ObjectPath extends object>(
obj: ObjectPath
): ObjectPath => {
const result = {} as ObjectPath;
const recursivePathCalculation = (
source: object,
rootPath: string[] = [],
target = result
) => {
for (const key in source) {
if (source.hasOwnProperty(key)) {
const path = rootPath.slice();
path.push(key);
const value = source[key];
if (value !== null && typeof value === "object") {
recursivePathCalculation(value, path, (target[key] = {}));
} else {
target[key] = path.join(".");
}
}
}
};
recursivePathCalculation(obj);
return result;
};
Ahora debemos exportar el objeto que usaremos en nuestra app usando esta función:
// 👉 Nuestro objeto mágico 🪄
export const tkeys = extractObjectPath({ ...es });
De este modo, conseguiremos apoyarnos en el autocompletado que nos facilita el IDE:
🔥 Aquí puedes probarla y ver el código completo:
👉 ¿No tienes TypeScript en tu proyecto? No pasa nada, aquí tienes la versión de JavaScript con JSDoc 💁♀️