@@ -50,12 +50,11 @@ module.exports = class Translator {
    * @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
    * taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
    *
-   * @param {string} phrase that needs interpolation, with placeholders
+   * @param {any} phrase that needs interpolation, with placeholders
    * @param {object} options with values that will be used to replace placeholders
-   * @returns {string} interpolated
+   * @returns {any[]} interpolated
    */
   interpolate (phrase, options) {
-    const { split, replace } = String.prototype
     const dollarRegex = /\$/g
     const dollarBillsYall = '$$$$'
     let interpolated = [phrase]
const has = require('./hasProperty')

/**
 * Translates strings with interpolation & pluralization support.
 * Extensible with custom dictionaries and pluralization functions.
 *
 * Borrows heavily from and inspired by Polyglot https://github.com/airbnb/polyglot.js,
 * basically a stripped-down version of it. Differences: pluralization functions are not hardcoded
 * and can be easily added among with dictionaries, nested objects are used for pluralization
 * as opposed to `||||` delimeter
 *
 * Usage example: `translator.translate('files_chosen', {smart_count: 3})`
 */
module.exports = class Translator {
  /**
   * @param {object|Array<object>} locales - locale or list of locales.
   */
  constructor (locales) {
    this.locale = {
      strings: {},
      pluralize (n) {
        if (n === 1) {
          return 0
        }
        return 1
      },
    }

    if (Array.isArray(locales)) {
      locales.forEach((locale) => this._apply(locale))
    } else {
      this._apply(locales)
    }
  }

  _apply (locale) {
    if (!locale || !locale.strings) {
      return
    }

    const prevLocale = this.locale
    this.locale = { ...prevLocale, strings: { ...prevLocale.strings, ...locale.strings } }
    this.locale.pluralize = locale.pluralize || prevLocale.pluralize
  }

  /**
   * Takes a string with placeholder variables like `%{smart_count} file selected`
   * and replaces it with values from options `{smart_count: 5}`
   *
   * @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
   * taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
   *
   * @param {string} phrase that needs interpolation, with placeholders
   * @param {object} options with values that will be used to replace placeholders
   * @returns {string} interpolated
   */
  interpolate (phrase, options) {
    const { split, replace } = String.prototype
    const dollarRegex = /\$/g
    const dollarBillsYall = '$$$$'
    let interpolated = [phrase]

    for (const arg in options) {
      if (arg !== '_' && has(options, arg)) {
        // Ensure replacement value is escaped to prevent special $-prefixed
        // regex replace tokens. the "$$$$" is needed because each "$" needs to
        // be escaped with "$" itself, and we need two in the resulting output.
        var replacement = options[arg]
        if (typeof replacement === 'string') {
          replacement = replace.call(options[arg], dollarRegex, dollarBillsYall)
        }
        // We create a new `RegExp` each time instead of using a more-efficient
        // string replace so that the same argument can be replaced multiple times
        // in the same phrase.
        interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement)
      }
    }

    return interpolated

    function insertReplacement (source, rx, replacement) {
      const newParts = []
      source.forEach((chunk) => {
        // When the source contains multiple placeholders for interpolation,
        // we should ignore chunks that are not strings, because those
        // can be JSX objects and will be otherwise incorrectly turned into strings.
        // Without this condition we’d get this: [object Object] hello [object Object] my <button>
        if (typeof chunk !== 'string') {
          return newParts.push(chunk)
        }

        split.call(chunk, rx).forEach((raw, i, list) => {
          if (raw !== '') {
            newParts.push(raw)
          }

          // Interlace with the `replacement` value
          if (i < list.length - 1) {
            newParts.push(replacement)
          }
        })
      })
      return newParts
    }
  }

  /**
   * Public translate method
   *
   * @param {string} key
   * @param {object} options with values that will be used later to replace placeholders in string
   * @returns {string} translated (and interpolated)
   */
  translate (key, options) {
    return this.translateArray(key, options).join('')
  }

  /**
   * Get a translation and return the translated and interpolated parts as an array.
   *
   * @param {string} key
   * @param {object} options with values that will be used to replace placeholders
   * @returns {Array} The translated and interpolated parts, in order.
   */
  translateArray (key, options) {
    if (!has(this.locale.strings, key)) {
      throw new Error(`missing string: ${key}`)
    }

    const string = this.locale.strings[key]
    const hasPluralForms = typeof string === 'object'

    if (hasPluralForms) {
      if (options && typeof options.smart_count !== 'undefined') {
        const plural = this.locale.pluralize(options.smart_count)
        return this.interpolate(string[plural], options)
      }
      throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}')
    }

    return this.interpolate(string, options)
  }
}

Hmm, I think we only allow string here and then all the jsx elements and such are inside the `options` object?