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.
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.
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.