Skip to content

Commit

Permalink
feat(iskey): adding new util to match property names and paths
Browse files Browse the repository at this point in the history
  • Loading branch information
roggervalf committed May 1, 2020
1 parent 6ddf3d1 commit 97e60ed
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/getTag.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Gets the `toStringTag` of `value`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
Expand Down
35 changes: 35 additions & 0 deletions src/isKey.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { isKey } from './isKey';

describe('isKey', () => {
describe('when only passing the value argument', () => {
it('should get true', () => {
expect(isKey(1)).toEqual(true);
expect(isKey(Symbol())).toEqual(true);
expect(isKey('attribute')).toEqual(true);
expect(isKey('spaced attribute')).toEqual(true);
expect(isKey(true)).toEqual(true);
expect(isKey(null)).toEqual(true);
expect(isKey(undefined)).toEqual(true);
});
it('should get false', () => {
expect(isKey([1, ''])).toEqual(false);
expect(isKey('something[test]')).toEqual(false);
expect(isKey('a.b')).toEqual(false);
});
});
describe('when passing the value and an object', () => {
const obj = {
'[a]': 5,
'b.c': true
};

it('should get true', () => {
expect(isKey('[a]', obj)).toEqual(true);
expect(isKey('b.c', obj)).toEqual(true);
});
it('should get false', () => {
expect(isKey('[b]', obj)).toEqual(false);
expect(isKey('c.d', obj)).toEqual(false);
});
});
});
55 changes: 55 additions & 0 deletions src/isKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { isSymbol } from './isSymbol';

/** Used to match property names within property paths. */
const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
const reIsPlainProp = /^\w*$/; //maches any word caracter (alphanumeric and underscore)

/**
* Checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value The value to check.
* @param {Object} [object] The object to query keys on.
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
* @example
* ```javascript
* isKey(1)
* // => true
*
* isKey('example[test]')
* // => false
*
* isKey('a.b')
* // => false
*
* const obj = {
* '[a]': 5,
* 'b.c': true
* };
*
* isKey('[a]', obj)
* // => true
*
* isKey('b.c', obj)
* // => true
* ```
*/
export function isKey(value: any, object?: object): boolean {
if (Array.isArray(value)) {
return false;
}
const type = typeof value;
if (
type === 'number' ||
type === 'boolean' ||
value === null ||
isSymbol(value)
) {
return true;
}
return (
reIsPlainProp.test(value) ||
!reIsDeepProp.test(value) ||
(object !== null && value in Object(object))
);
}
1 change: 1 addition & 0 deletions src/memoizeCapped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const MAX_MEMOIZE_SIZE = 500;
/**
* A specialized version of `memoize` which clears the memoized function's
* cache when it exceeds `MAX_MEMOIZE_SIZE`.
*
* @private
* @param {Function} func The function to have its output memoized.
* @returns {Function} Returns the new memoized function.
Expand Down

0 comments on commit 97e60ed

Please sign in to comment.