Flow: boolean cannot be coerced to string

Created on 30 Sep 2016  路  6Comments  路  Source: facebook/flow

I was surprised to find that boolean values could not be used directly in string interpolations (for logging in my case) with Flow 0.33.0.

/* @flow */

const x = `${true}`;

Error:

3: const x = `${true}`;
                ^ boolean. This type cannot be coerced to
3: const x = `${true}`;
             ^ string

Am I overlooking a problem here, or should this work? If not, what would be a suggested workaround? Adding bool_var ? 'true' : 'false' everywhere would only make the code looks worse IMHO.

Most helpful comment

Flow tries to help catch unintended string-casts, so you'll just need to wrap the bool with String(true) here to convey that explicit intent to cast.

cc @mroch for context since he's been trying to find a good balance for this stuff lately.

All 6 comments

Flow tries to help catch unintended string-casts, so you'll just need to wrap the bool with String(true) here to convey that explicit intent to cast.

cc @mroch for context since he's been trying to find a good balance for this stuff lately.

I have something like this:

type AllowedHttpCodes = 400 | 401 | 403 | 404 | 422 | 500 | 502 | 502 | 504;

// this works
const x = `${String(true)} - whatever`;

// but not this
const errorBuilder = (name : string, errorCode : AllowedHttpCodes) => {
  function NewErrorType(message : ?string | ?boolean | ?number) {
    this.name = name;
    this.message = `[${String(errorCode)}] ${message}`;
    this.stack = (new Error()).stack;
  }

  NewErrorType.prototype = new Error();
  NewErrorType.prototype.toApiGatewayString = function () {
    return this.message;
  };
  return NewErrorType;
};

which gives me:

lib/commons/errors.js:10
 10:     this.message = `[${String(errorCode)}] ${message}`;
                                                  ^^^^^^^ boolean. This type cannot be coerced to
 10:     this.message = `[${String(errorCode)}] ${message}`;
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string

lib/commons/errors.js:10
 10:     this.message = `[${String(errorCode)}] ${message}`;
                                                  ^^^^^^^ null. This type cannot be coerced to
 10:     this.message = `[${String(errorCode)}] ${message}`;
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string

lib/commons/errors.js:10
 10:     this.message = `[${String(errorCode)}] ${message}`;
                                                  ^^^^^^^ undefined. This type cannot be coerced to
 10:     this.message = `[${String(errorCode)}] ${message}`;
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string

any suggestions on how to fix this?

Doing this.message = `[${String(errorCode)}] ${String(message)}`; will solve your problem :) As explained earlier, you need to explicitly cast your boolean to string.

thanks @AugustinLF. silly me. not sure how I could missed that error message.

I get why const str2: string = (str: string) + (bool: boolean) should be prevented, but perhaps template strings should allow implicit type-casting for primitive values.

What do you think, @vkurchatkin?

Flow tries to limit implicit behaviour. The line is kind of arbitrary, but I personally agree with the current way it's implemented.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TylerEich picture TylerEich  路  49Comments

jamesisaac picture jamesisaac  路  44Comments

gabro picture gabro  路  57Comments

sophiebits picture sophiebits  路  66Comments

Macil picture Macil  路  47Comments