├── .gitignore ├── index.d.ts ├── index.js ├── package-lock.json ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare function isMergeableObject(value: any): boolean; 2 | 3 | export default isMergeableObject; 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = function isMergeableObject(value) { 2 | return isNonNullObject(value) 3 | && !isSpecial(value) 4 | } 5 | 6 | function isNonNullObject(value) { 7 | return !!value && typeof value === 'object' 8 | } 9 | 10 | function isSpecial(value) { 11 | var stringValue = Object.prototype.toString.call(value) 12 | 13 | return stringValue === '[object RegExp]' 14 | || stringValue === '[object Date]' 15 | || isReactElement(value) 16 | } 17 | 18 | // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 19 | var canUseSymbol = typeof Symbol === 'function' && Symbol.for 20 | var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7 21 | 22 | function isReactElement(value) { 23 | return value.$$typeof === REACT_ELEMENT_TYPE 24 | } 25 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "is-mergeable-object", 3 | "version": "1.1.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "deep-is": { 8 | "version": "0.1.3", 9 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 10 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 11 | "dev": true 12 | }, 13 | "escodegen": { 14 | "version": "1.11.1", 15 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", 16 | "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", 17 | "dev": true, 18 | "requires": { 19 | "esprima": "^3.1.3", 20 | "estraverse": "^4.2.0", 21 | "esutils": "^2.0.2", 22 | "optionator": "^0.8.1", 23 | "source-map": "~0.6.1" 24 | }, 25 | "dependencies": { 26 | "esprima": { 27 | "version": "3.1.3", 28 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 29 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", 30 | "dev": true 31 | } 32 | } 33 | }, 34 | "esprima": { 35 | "version": "2.7.3", 36 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 37 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 38 | "dev": true 39 | }, 40 | "estraverse": { 41 | "version": "4.2.0", 42 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 43 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 44 | "dev": true 45 | }, 46 | "esutils": { 47 | "version": "2.0.2", 48 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 49 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 50 | "dev": true 51 | }, 52 | "fast-levenshtein": { 53 | "version": "2.0.6", 54 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 55 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 56 | "dev": true 57 | }, 58 | "jsmd": { 59 | "version": "1.0.1", 60 | "resolved": "https://registry.npmjs.org/jsmd/-/jsmd-1.0.1.tgz", 61 | "integrity": "sha512-fcNxki98MSYdJyWj9jjbSrQkd+ptYLRgb3HgLMZxALI9TznqbqmTImBhWei2GkOSerX84Ve8Swq6AYqCrti8dw==", 62 | "dev": true, 63 | "requires": { 64 | "escodegen": "^1.9.1", 65 | "esprima": "^2.7.3", 66 | "estraverse": "^4.2.0", 67 | "marked": "0.6.2", 68 | "v8-argv": "github:jkroso/v8-argv#1.1.1" 69 | } 70 | }, 71 | "levn": { 72 | "version": "0.3.0", 73 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 74 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 75 | "dev": true, 76 | "requires": { 77 | "prelude-ls": "~1.1.2", 78 | "type-check": "~0.3.2" 79 | } 80 | }, 81 | "marked": { 82 | "version": "0.6.2", 83 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz", 84 | "integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA==", 85 | "dev": true 86 | }, 87 | "optionator": { 88 | "version": "0.8.2", 89 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 90 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 91 | "dev": true, 92 | "requires": { 93 | "deep-is": "~0.1.3", 94 | "fast-levenshtein": "~2.0.4", 95 | "levn": "~0.3.0", 96 | "prelude-ls": "~1.1.2", 97 | "type-check": "~0.3.2", 98 | "wordwrap": "~1.0.0" 99 | } 100 | }, 101 | "prelude-ls": { 102 | "version": "1.1.2", 103 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 104 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 105 | "dev": true 106 | }, 107 | "source-map": { 108 | "version": "0.6.1", 109 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 110 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 111 | "dev": true, 112 | "optional": true 113 | }, 114 | "type-check": { 115 | "version": "0.3.2", 116 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 117 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 118 | "dev": true, 119 | "requires": { 120 | "prelude-ls": "~1.1.2" 121 | } 122 | }, 123 | "v8-argv": { 124 | "version": "github:jkroso/v8-argv#284f84379e292eb956a5e7b66fb953ec4974385e", 125 | "from": "github:jkroso/v8-argv#1.1.1", 126 | "dev": true 127 | }, 128 | "wordwrap": { 129 | "version": "1.0.0", 130 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 131 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 132 | "dev": true 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "is-mergeable-object", 3 | "version": "1.1.1", 4 | "description": "Check whether or not a value is an object that makes sense to iterate over", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "test": "jsmd readme.md" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+ssh://git@github.com/TehShrike/is-mergeable-object.git" 13 | }, 14 | "keywords": [ 15 | "object", 16 | "iterate", 17 | "recursive", 18 | "merge", 19 | "deep" 20 | ], 21 | "author": "TehShrike", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/TehShrike/is-mergeable-object/issues" 25 | }, 26 | "homepage": "https://github.com/TehShrike/is-mergeable-object#readme", 27 | "devDependencies": { 28 | "jsmd": "^1.0.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # is-mergeable-object 2 | 3 | 6 | 7 | The biggest difficulty deep merge libraries run into is figuring out which properties of an object should be recursively iterated over. 8 | 9 | This module contains the algorithm used by [`deepmerge`](https://github.com/KyleAMathews/deepmerge/). 10 | 11 | 16 | 17 | ```js 18 | isMergeableObject(null) // => false 19 | 20 | isMergeableObject({}) // => true 21 | 22 | isMergeableObject(new RegExp('wat')) // => false 23 | 24 | isMergeableObject(undefined) // => false 25 | 26 | isMergeableObject(new Object()) // => true 27 | 28 | isMergeableObject(new Date()) // => false 29 | 30 | isMergeableObject(someReactElement) // => false 31 | ``` 32 | --------------------------------------------------------------------------------