-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert casted values #25
Comments
Hello @panoply, thanks for the issue!
I wanted to get the same result as chalk and picocolors for "compatibility". We can discuss the behaviour of all edge cases to work out the most optimal and expected result. Currently behaviour:
See the test/functional.test.js Your proposals (please complete)
P.S.Any PR is wellcome! |
However using a template string, let foo; // undefined
console.log(`Hello ${foo}!`); // => Hello undefined! Therefore would be best keep the same behaviour for consistency: import { red, green } from 'ansis';
let foo; // undefined
console.log(green`Hello ${red(foo)}!`); // => \x1b[32mHello \x1b[31mundefined\x1b[32m!\x1b[39m |
Both variants are valid. It would be good to conduct a survey on stackoverflow and reddit. |
I will try to explain the changes. Expected behaviour for developer-friendliness
let foo; // undefined
console.log(ansis.red(foo)); // => 'undefined' in red
let foo; // undefined
console.log(ansis.green(`Hello ${ansis.red(foo)}!`)); // => 'Hello undefined!' with 'undefined' in red Why this behaviour is developer-friendly?
Libraries like Chalk, Picocolors, and many others follow the "stringify and colorize" approach for |
here is the same discussion by colorette |
Hey @webdiscus Sorry for not being clearer in the issue; I was multitasking when I submitted it (not my strong suit). To circle back and provide more context: while I personally understand the decision to use type casting, and for the majority, this might suffice or never really be an issue, I argue that ANSI modules like ansis, which are designed for string manipulation and highlighting, should adhere to string conventions. Casting to SuggestionIf you strongly prefer to retain value casting, I would suggest exposing a global opt-out mechanism. Alternatively, if you agree with my perspective, casting could instead be made opt-in. Since ansis is designed for non-browser runtimes, leveraging a global variable would be both convenient and unobtrusive. For example: process.env['ANSIS'] = '' // Environment variable to toggle casting A potentially better solution, however, would be to provide this option directly on the ansis instance itself, as it would allow for casting to be toggled at different points, e.g: import ansis from 'ansis';
ansis.type_casting = false; RE "compatibility"
I wasn’t aware that casting was used in picocolors/colorette. While I actively avoid using modules written or maintained by Sindre and have no interest in Chalk (so couldn't care less about it), I was genuinely surprised to learn that such behaviour is common among soo many ANSI libraries. My statement about consistency was based on ansi-colors, which defaults to an empty string. FWIW One of the main reasons I chose ansis is the internal algorithm you’ve developed for highlighting. Personally, I’m fine with less "compatibility" and would much prefer to see ansis become the standard rather than conform to others. |
thanks for your answer! Your arguments are weighty and quite reasonable. P.S. Ansis works w/o options to keep the same result. |
But I see a different result: console.log(String()); // => empty string, OK
console.log(String(null)); // => null
console.log(String(undefined)); // => undefined
console.log(String(NaN)); // => NaN It looks like this is the expected behavior, at least according to the JS standard.
I'm for common convention and widely used best practices. |
let's first agree on the following values:
It's Ok? |
What do you think about For example: let foo = 100/'5px'; // NaN, yes it's developer error, but it should not be displayed as an empty string
ansis.green(foo); // => '\x1b[32mNaN\x1b[39m' I think |
here are results of import ansiColors from 'ansi-colors';
console.log(ansiColors.green()); // => empty string
console.log(ansiColors.green(null)); // => empty string
console.log(ansiColors.green(undefined)); // => empty string
console.log(ansiColors.green('')); // => empty string
console.log(ansiColors.green(true)); // => true
console.log(ansiColors.green(false)); // => false
console.log(ansiColors.green(0)); // => 0
console.log(ansiColors.green(NaN)); // => NaN
console.log(ansiColors.green(1/0)); // => Infinity I think these are the usualy expected results. |
Agreed.
Yes, I'd say the conditions that ansi-colors employed is on the mark here, where
I'd happily settle for that. |
In See please the handling edge cases in readme. P.S. Thank you for the constructive discussion! |
Thanks @webdiscus – Much appreciate the time and discourse. |
Current behaviour
As of 3.7.0 the change to casted values is returning
undefined
which is not ideal and problematic with implementations where primitives should not be stringified.Expected behaviour
Result should be empty string.
Reproduction Example
In the below example,
foo
is undefined, but it is not ansis job to cast that, failing silently is far better imo as per the previous versions. The argument for type checking before printing can also be a nuance because it is assumed behaviour based on alternative libs.Additional context
While the logic is good in theory, in practice it is not ideal.
The text was updated successfully, but these errors were encountered: