# 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](https://www.i18next.com/), 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1612787682575/22cD8pWMV.gif)

🔥 Aquí puedes probarla y ver el código completo:

%[https://codesandbox.io/s/i18n-con-typescript-jdxr0?file=/src/App.tsx]

👉 ¿No tienes TypeScript en tu proyecto? No pasa nada, aquí tienes la [versión de JavaScript con JSDoc](https://lissetteibnz.es/utilizar-i18n-de-una-forma-mas-eficiente-version-js-y-jsdoc) 💁‍♀️

#### Recursos:
- [i18n API](https://developer.mozilla.org/es/docs/Mozilla/Add-ons/WebExtensions/API/i18n)
- [Wiki i18n](https://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_y_localizaci%C3%B3n)
- [i18n-next](https://www.i18next.com/)

