0

As part of a library I write, I want to let the user to pass functions as object's keys:

https://github.com/welldone-software/redux-toolbelt/tree/master/packages/redux-toolbelt#makereducer

For example, in the following, increaseBy is a function with a custom toString() that returns a string and decreaseBy.TYPE is a string.

const reducer = makeReducer({
  [increaseBy]: (state, {payload}) => state + payload,
  [decreaseBy.TYPE]: (state, {payload}) => state - payload,
}, { defaultState: 100 })

Where increaseBy is a function that has a custom toString() that resolves to a string.

JS translates any key to string using toString() so it works, but my question is:

how safe is it?

Vitali Zaidman
  • 899
  • 1
  • 9
  • 24
  • 1
    Technically, it is safe in an ES2015 environment. However, you now rely on implicit type coercion. Everyone looking at your code can't immediately tell what property names the object has. And consider functions without a custom `toString`: `const id = x => x; o = {[id]: "foo"}` yields `{x => x: "foo"}`. –  Oct 16 '17 at 09:31
  • Yes, I know that. If you look at our library it is clear from the flow. I don't just assign a random function with custom `toString()` on it as object's key :) – Vitali Zaidman Oct 16 '17 at 16:43

1 Answers1

2

According to the ES6 specification, under section "12.2.6.8 Runtime Semantics: Evaluation" for "ComputedPropertyName" in the fourth step we have:

  1. Return ToPropertyKey(propName).

which under "7.1.14 ToPropertyKey ( argument )" in the fourth step:

  1. Return ToString(key).

So the result of [expression] will become toString. On the other hand any string is a valid key for a property, though some of them can only be accessed via brackets.

frogatto
  • 28,539
  • 11
  • 83
  • 129