Flow: Implicitly call `toString` with string concatenation

Created on 26 Feb 2016  路  5Comments  路  Source: facebook/flow

Consider the following example:

class X {
  toString() { return ""; }
}

console.log( "a" + new X)

This fails with:

  5: console.log( "" + new X )
                           ^ X. This type is incompatible with
  5: console.log( "" + new X )
                  ^^^^^^^^^^ string

I understand that implicit conversions can be a source of mistakes, but in a case where a user-defined class explicitly implements a toString method, such a concatenation doesn't seem to risky.

Most helpful comment

fwiw I'd favor encouraging the explicit .toString() call

All 5 comments

fwiw I'd favor encouraging the explicit .toString() call

I'm inclined to agree with @jaredly. In our experience, implicit casts are more often than not unintended. However, we do permit a number of implicit casts. Flow accepts 100 + '%', for example.

What we really need to reconsider this choice is a compelling argument that this implicit cast represents a common JS idiom, such that allowing it would help Flow to understand more idiomatic JS code.

I appreciate the minimal example code in the original issue, but think it is insufficient to reconsider this tradeoff. A more complete example is needed here.

Thanks!

@samwgoldman and @jaredly. Notice for you, that @adrianheine right here and this issue is correct.
Please follow to https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/toString and find

Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected.

Ok, maybe default behaviour ("[object Object]") not correct. But developer can override this method and return custom string. Very popular example is Mongodb ObjectID method:

ObjectID() // {_bsontype: "ObjectID", id: Buffer[12]}
`${ObjectID()}` // "57e8f815f183c94e2bd340d0"

Flow should try to find custom toString method and make sure, that it returns string. It means, that developer setup custom stringify behaviour for object and it is correct.

@darky all kinds of things are valid JS that flow disallows :) it's all about enforcing conventions. If you want to rally support for this, though, go right ahead. I haven't (intentionally) used this js "feature" super often, but maybe other people do

For now we are going to keep this behavior. If anyone has a strong usecase for why this would be useful let us know 馃槉

Otherwise we are going to have an opinion on this 馃憤

Was this page helpful?
0 / 5 - 0 ratings