Repository: sindresorhus/query-string (js)

Issue:
Add parseBooleans option
Parsing an object like 
```javascript
{
    test: true
}
```
results in `test=true`. Using stringify it results in
```javascript
{
    test: "true"
}
```

That's why I think we need an additional option like parseNumbers for booleans.

Pull request description:
Add `parseBooleans` option to `.parse()`
Fixes #182 

Patch:
diff --git a/index.d.ts b/index.d.ts
index 024c58b..4b97e1f 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -74,10 +74,23 @@ export interface ParseOptions {
 	```
 	*/
 	readonly parseNumbers?: boolean;
+
+	/**
+	Parse the value as a boolean type instead of string type if it's a boolean.
+
+	@default false
+
+	@example
+	```
+	queryString.parse('foo=true', {parseBooleans: true});
+	//=> {foo: true}
+	```
+	*/
+	readonly parseBooleans?: boolean;
 }
 
 export interface ParsedQuery {
-	readonly [key: string]: string | number | Array<string | number> | null | undefined;
+	readonly [key: string]: string | number | boolean | Array<string | number | boolean> | null | undefined;
 }
 
 /**
diff --git a/index.js b/index.js
index 677cc5b..552baa4 100644
--- a/index.js
+++ b/index.js
@@ -176,7 +176,8 @@ function parse(input, options) {
 		decode: true,
 		sort: true,
 		arrayFormat: 'none',
-		parseNumbers: false
+		parseNumbers: false,
+		parseBooleans: false
 	}, options);
 
 	const formatter = parserForArrayFormat(options);
@@ -205,6 +206,10 @@ function parse(input, options) {
 			value = Number(value);
 		}
 
+		if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {
+			value = value.toLowerCase() === 'true';
+		}
+
 		formatter(decode(key, options), value, ret);
 	}
 
diff --git a/readme.md b/readme.md
index 643fde3..297a47d 100644
--- a/readme.md
+++ b/readme.md
@@ -115,6 +115,18 @@ queryString.parse('foo=1', {parseNumbers: true});
 
 Parse the value as a number type instead of string type if it's a number.
 
+##### parseBooleans
+
+Type: `boolean`<br>
+Default: `false`
+
+```js
+queryString.parse('foo=true', {parseBooleans: true});
+//=> {foo: true}
+```
+
+Parse the value as a boolean type instead of string type if it's a boolean.
+
 ### .stringify(object, [options])
 
 Stringify an object into a query string and sorting the keys.


Test patch:
diff --git a/index.test-d.ts b/index.test-d.ts
index eddfc3c..b3f9bb4 100644
--- a/index.test-d.ts
+++ b/index.test-d.ts
@@ -54,6 +54,9 @@ expectType<queryString.ParsedQuery>(
 expectType<queryString.ParsedQuery>(
 	queryString.parse('?foo=1', {parseNumbers: true})
 );
+expectType<queryString.ParsedQuery>(
+	queryString.parse('?foo=true', {parseBooleans: true})
+);
 
 // Parse URL
 expectType<queryString.ParsedUrl>(queryString.parseUrl('?foo=bar'));
@@ -73,8 +76,11 @@ expectType<queryString.ParsedUrl>(
 expectType<queryString.ParsedUrl>(
 	queryString.parseUrl('?foo=bar', {arrayFormat: 'comma'})
 );
-expectType<queryString.ParsedQuery>(
-	queryString.parse('?foo=1', {parseNumbers: true})
+expectType<queryString.ParsedUrl>(
+	queryString.parseUrl('?foo=1', {parseNumbers: true})
+);
+expectType<queryString.ParsedUrl>(
+	queryString.parseUrl('?foo=true', {parseBooleans: true})
 );
 
 // Extract
diff --git a/test/parse.js b/test/parse.js
index 96e8202..61bba90 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -244,3 +244,12 @@ test('NaN value returns as string if option is set', t => {
 	t.deepEqual(queryString.parse('foo=undefined', {parseNumbers: true}), {foo: 'undefined'});
 	t.deepEqual(queryString.parse('foo=100a&bar=100', {parseNumbers: true}), {foo: '100a', bar: 100});
 });
+
+test('boolean value returns as string by default', t => {
+	t.deepEqual(queryString.parse('foo=true'), {foo: 'true'});
+});
+
+test('boolean value returns as boolean if option is set', t => {
+	t.deepEqual(queryString.parse('foo=true', {parseBooleans: true}), {foo: true});
+	t.deepEqual(queryString.parse('foo=false&bar=true', {parseBooleans: true}), {foo: false, bar: true});
+});