fnando / i18n

A small library to provide the I18n translations on the JavaScript.
https://fnando.github.io/i18n/
MIT License
169 stars 20 forks source link

Bug: Incorrect translation when using numbers as keys #72

Closed woutersmeenk closed 1 year ago

woutersmeenk commented 1 year ago

Description

We use i18n-js with translations for units and we request the translations of the entire set of units. This used to work in previous versions but after switching to version 4 this results in a incomplete array. When we remove '1' key the problem is solved.

Thank you for your great work on this package!

How to reproduce

import { I18n } from 'i18n-js'

export const i18n = new I18n()

i18n.store({ 'en': { 'units': { 'l': 'liter', '1': 'number' } } })
console.log(i18n.t('units'))
console.log(i18n.t('units.1'))
console.log(i18n.t('units.l'))

What do you expect

Expected this console output:

Object { l: "liter", 1: "number" }
number
liter

This is also what version 3.9.2 of i18n-js returned (using a similar setup).

What happened instead

This console output:

Array [ <1 empty slot>, "number" ]
number
liter

Software:

fnando commented 1 year ago

The problem seems to be in lodash's set function, which treats numeric indexes to create arrays instead. Honestly, this is a hard problem to solve because how can we discern from actual arrays? 🤔

It's also order dependent when storing translations, because if you do it separately, it works:

i18n.store({ en: { units: { l: "liter" } } });
i18n.store({ en: { units: { "1": "number" } } });

I guess we can detect whether the key is a string; if so, forcefully use an object rather than an array.