17

I am trying to convert a string to boolean. There are several ways of doing it one way is

let input = "true";
let boolVar = (input === 'true');

The problem here is that I have to validate input if it is true or false. Instead of validating first input and then do the conversion is there any more elegant way? In .NET we have bool.TryParse which returns false if the string is not valid. Is there any equivalent in typescript?

pantonis
  • 5,601
  • 12
  • 58
  • 115
  • 3
    I don't know about .NET, but if `bool.TryParse` returns `false` on "invalid" strings… isn't that the same as *returning `true` if string is `"true"` else `false`*…? Exactly what you're doing already? – deceze May 17 '17 at 12:00
  • If someone types "John" John is not a valid bool. That does not mean it is false. – pantonis May 17 '17 at 12:04
  • 1
    But isn't that what the .NET thing you described does? I pass it "John", that's not valid, it returns false. I still don't see the difference. – takendarkk May 17 '17 at 12:06
  • The `tryParse` in .NET returns both the validness AND the result. (The second parameter is a refference that will be set to the actual outcome, while it returns whether it successfully parsed it or not.) – Ivar May 17 '17 at 12:08
  • @Ivar So it returns `false` and `false`? That makes more sense. And such a thing is not built into Javascript. – deceze May 17 '17 at 12:17
  • @deceze You are correct. – Ivar May 17 '17 at 12:22
  • 2
    You can do `JSON.parse(string)` and if it throws an exception you can infer it is not valid. – Saravana May 17 '17 at 12:40
  • not sure there really is anything better than this: http://stackoverflow.com/questions/263965/how-can-i-convert-a-string-to-boolean-in-javascript?rq=1 . – briosheje May 17 '17 at 14:02
  • @csm_dev as Ivar described .NET returns both the validness AND the result. – pantonis May 17 '17 at 14:10

6 Answers6

25

You can do something like this where you can have three states. undefined indicates that the string is not parseable as boolean:

function convertToBoolean(input: string): boolean | undefined {
    try {
        return JSON.parse(input.toLowerCase());
    }
    catch (e) {
        return undefined;
    }
}

console.log(convertToBoolean("true")); // true
console.log(convertToBoolean("false")); // false
console.log(convertToBoolean("True")); // true
console.log(convertToBoolean("False")); // false
console.log(convertToBoolean("invalid")); // undefined
Saravana
  • 37,852
  • 18
  • 100
  • 108
6

Returns true for 1, '1', true, 'true' (case-insensitive) . Otherwise false

function primitiveToBoolean(value: string | number | boolean | null | undefined): boolean {
  if (typeof value === 'string') {
    return value.toLowerCase() === 'true' || !!+value;  // here we parse to number first
  }

  return !!value;
}

Here is Unit test:

describe('primitiveToBoolean', () => {
  it('should be true if its 1 / "1" or "true"', () => {
    expect(primitiveToBoolean(1)).toBe(true);
    expect(primitiveToBoolean('1')).toBe(true);
    expect(primitiveToBoolean('true')).toBe(true);
  });
  it('should be false if its 0 / "0" or "false"', () => {
    expect(primitiveToBoolean(0)).toBe(false);
    expect(primitiveToBoolean('0')).toBe(false);
    expect(primitiveToBoolean('false')).toBe(false);
  });
  it('should be false if its null or undefined', () => {
    expect(primitiveToBoolean(null)).toBe(false);
    expect(primitiveToBoolean(undefined)).toBe(false);
  });
  it('should pass through booleans - useful for undefined checks', () => {
    expect(primitiveToBoolean(true)).toBe(true);
    expect(primitiveToBoolean(false)).toBe(false);
  });
    it('should be case insensitive', () => {
    expect(primitiveToBoolean('true')).toBe(true);
    expect(primitiveToBoolean('True')).toBe(true);
    expect(primitiveToBoolean('TRUE')).toBe(true);
  });
});

TypeScript Recipe: Elegant Parse Boolean (ref. to original post)

am0wa
  • 7,724
  • 3
  • 38
  • 33
5

You could also use an array of valid values:

const toBoolean = (value: string | number | boolean): boolean => 
    [true, 'true', 'True', 'TRUE', '1', 1].includes(value);

Or you could use a switch statement as does in this answer to a similar SO question.

What Would Be Cool
  • 6,204
  • 5
  • 45
  • 42
0

If you are sure you have a string as input I suggest the following. It can be the case when retrieving an environment variable for example with process.env in Node

function toBoolean(value?: string): boolean {
  if (!value) {
    //Could also throw an exception up to you
    return false
  }

  switch (value.toLocaleLowerCase()) {
    case 'true':
    case '1':
    case 'on':
    case 'yes':
      return true
    default:
      return false
  }
}

https://codesandbox.io/s/beautiful-shamir-738g5?file=/src/index.ts

Ronan Quillevere
  • 3,699
  • 1
  • 29
  • 44
0

Here is a simple version,

function parseBoolean(value?: string | number | boolean | null) {
    value = value?.toString().toLowerCase();
    return value === 'true' || value === '1';
}
XzaR
  • 610
  • 1
  • 7
  • 17
-5

I suggest that you want boolVar to be true for input equals true and input equals "true" (same for false) else it should be false.

let input = readSomeInput(); // true,"true",false,"false", {}, ...
let boolVar = makeBoolWhateverItIs(input);

function makeBoolWhateverItIs(input) {
    if (typeof input == "boolean") {
       return input;
    } else if typeof input == "string" {
       return input == "true";  
    }
    return false;
}
MG83
  • 16
  • 5
  • 2
    `Boolean(input)` will always return true as long as the string is not empty. So you are basically just doing `let boolVar = (input === 'true')`, which is the question in the first place. And even if it would work the way you expect, then still it doesn't make a difference between false and a non-boolean string. – Ivar May 17 '17 at 13:08
  • Thats not true because Boolean("someOtherString") will return false, Boolean({}) will return false. So if your not sure that your input is a string (let could be any type) this is a good solution. true === "true" will also be false so you have to ensure that the type of input ist String but its let, so it could be everything. – MG83 May 17 '17 at 13:52
  • `Boolean("someOtherString")` will be true. [Try it out](https://jsfiddle.net/gdp0vLvc/). From the question I understand that the input will always be a string. And as I said, even if you would be right, than it still doesn't separately check if the parse fails or not. – Ivar May 17 '17 at 13:58
  • Also `Boolean({})` will return true. And `true == 'true'` will be false as well. – Ivar May 17 '17 at 14:01
  • You are right this does not make any sense to me but your right. – MG83 May 17 '17 at 14:07