Repository: sindresorhus/dot-prop (js)

Issue:
deepKeys returns strange result
```deepKeys({ x: 1, y: "1", z: [1], zz: [], o: {}, n: null, u: undefined, nan: NaN })```

returns

```['x', 'y', 'z[0]', 'n', 'u', 'nan']```

Why is it missing `zz` and `o`, for me it is looks as bug

Pull request:
fix deepkeys to work with empty arrays and objects
fix #104 

Patch:
diff --git a/index.d.ts b/index.d.ts
index 0eaa13a..8e22a07 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -133,7 +133,7 @@ console.log(getProperty(object, escapedPath));
 export function escapePath(path: string): string;
 
 /**
-Returns an array of every path. Plain objects are deeply recursed and are not themselves included.
+Returns an array of every path. Non-empty plain objects and arrays are deeply recursed and are not themselves included.
 
 This can be useful to help flatten an object for an API that only accepts key-value pairs or for a tagged template literal.
 
@@ -148,12 +148,16 @@ const user = {
 		first: 'Richie',
 		last: 'Bendall',
 	},
+	activeTasks: [],
+	currentProject: null
 };
 
 for (const property of deepKeys(user)) {
 	console.log(`${property}: ${getProperty(user, property)}`);
 	//=> name.first: Richie
 	//=> name.last: Bendall
+	//=> activeTasks: []
+	//=> currentProject: null
 }
 ```
 */
diff --git a/index.js b/index.js
index c4abc95..e699982 100644
--- a/index.js
+++ b/index.js
@@ -3,6 +3,8 @@ const isObject = value => {
 	return value !== null && (type === 'object' || type === 'function');
 };
 
+const isEmptyObject = value => isObject(value) && Object.keys(value).length === 0;
+
 const disallowedKeys = new Set([
 	'__proto__',
 	'prototype',
@@ -316,7 +318,7 @@ function stringifyPath(pathSegments) {
 }
 
 function * deepKeysIterator(object, currentPath = []) {
-	if (!isObject(object)) {
+	if (!isObject(object) || isEmptyObject(object)) {
 		if (currentPath.length > 0) {
 			yield stringifyPath(currentPath);
 		}
diff --git a/readme.md b/readme.md
index b0ed66e..a5d7baf 100644
--- a/readme.md
+++ b/readme.md
@@ -110,7 +110,7 @@ console.log(getProperty(object, escapedPath));
 
 ### deepKeys(object)
 
-Returns an array of every path. Plain objects are deeply recursed and are not themselves included.
+Returns an array of every path. Non-empty plain objects and arrays are deeply recursed and are not themselves included.
 
 This can be useful to help flatten an object for an API that only accepts key-value pairs or for a tagged template literal.
 
@@ -122,12 +122,16 @@ const user = {
 		first: 'Richie',
 		last: 'Bendall',
 	},
+	activeTasks: [],
+	currentProject: null
 };
 
 for (const property of deepKeys(user)) {
 	console.log(`${property}: ${getProperty(user, property)}`);
 	//=> name.first: Richie
 	//=> name.last: Bendall
+	//=> activeTasks: []
+	//=> currentProject: null
 }
 ```
 


Test patch:
diff --git a/test.js b/test.js
index 556d810..17cf1c7 100644
--- a/test.js
+++ b/test.js
@@ -413,6 +413,8 @@ test('escapePath', t => {
 
 test('deepKeys', t => {
 	const object = {
+		eo: {},
+		ea: [],
 		'a.b': {
 			c: {
 				d: [1, 2, {
@@ -420,6 +422,11 @@ test('deepKeys', t => {
 				}],
 				e: '🦄',
 				f: 0,
+				h: {},
+				i: [],
+				nu: null,
+				na: Number.NaN,
+				un: undefined,
 			},
 			'': {
 				a: 0,
@@ -432,11 +439,18 @@ test('deepKeys', t => {
 	const keys = deepKeys(object);
 
 	t.deepEqual(keys, [
+		'eo',
+		'ea',
 		'a\\.b.c.d[0]',
 		'a\\.b.c.d[1]',
 		'a\\.b.c.d[2].g',
 		'a\\.b.c.e',
 		'a\\.b.c.f',
+		'a\\.b.c.h',
+		'a\\.b.c.i',
+		'a\\.b.c.nu',
+		'a\\.b.c.na',
+		'a\\.b.c.un',
 		'a\\.b..a',
 		'.a',
 	]);