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:

DemoTKeys.gif

🔥 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 💁‍♀️

Recursos: