Skip to content

Commit

Permalink
feat(compat) : implement isSet/isMap (#643)
Browse files Browse the repository at this point in the history
* feat : add isMap compat

* feat : isMap/compat bench

* feat : add isSet compat

* Update benchmarks/performance/isMap.bench.ts

Co-authored-by: D-Sketon <[email protected]>

* Update benchmarks/performance/isSet.bench.ts

Co-authored-by: D-Sketon <[email protected]>

* Apply suggestions from code review

---------

Co-authored-by: D-Sketon <[email protected]>
Co-authored-by: Sojin Park <[email protected]>
  • Loading branch information
3 people authored Oct 3, 2024
1 parent 22b136f commit 57155d7
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 0 deletions.
11 changes: 11 additions & 0 deletions benchmarks/performance/isMap.bench.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { bench, describe } from 'vitest';
import { isMap as isMapToolkit_ } from 'es-toolkit';
import { isMap as isMapToolkitCompat_ } from 'es-toolkit/compat'
import { isMap as isMapLodash_ } from 'lodash';

const isMapToolkit = isMapToolkit_;
const isMapToolkitCompat = isMapToolkitCompat_ ;
const isMapLodash = isMapLodash_;

describe('isMap', () => {
Expand All @@ -15,6 +17,15 @@ describe('isMap', () => {
isMapToolkit(null);
});

bench('es-toolkit/compat/isMap', () => {
isMapToolkitCompat(new Map());
isMapToolkitCompat(new Map([['key', 'value']]));
isMapToolkitCompat(new WeakMap());
isMapToolkitCompat([]);
isMapToolkitCompat({});
isMapToolkitCompat(null);
});

bench('lodash/isMap', () => {
isMapLodash(new Map());
isMapLodash(new Map([['key', 'value']]));
Expand Down
10 changes: 10 additions & 0 deletions benchmarks/performance/isSet.bench.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { bench, describe } from 'vitest';
import { isSet as isSetToolkit_ } from 'es-toolkit';
import { isSet as isSetToolkitCompat_ } from 'es-toolkit/compat';
import { isSet as isSetLodash_ } from 'lodash';

const isSetToolkit = isSetToolkit_;
const isSetToolkitCompat = isSetToolkitCompat_;
const isSetLodash = isSetLodash_;

describe('isSet', () => {
Expand All @@ -14,6 +16,14 @@ describe('isSet', () => {
isSetToolkit(null);
});

bench('es-toolkit/isSetCompat', () => {
isSetToolkitCompat(new Set());
isSetToolkitCompat(new WeakSet());
isSetToolkitCompat([]);
isSetToolkitCompat({});
isSetToolkitCompat(null);
});

bench('lodash/isSet', () => {
isSetLodash(new Set());
isSetLodash(new WeakSet());
Expand Down
1 change: 1 addition & 0 deletions src/compat/_internal/weakMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const weakMap = new WeakMap();
1 change: 1 addition & 0 deletions src/compat/_internal/weakSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const weakSet = new WeakSet();
2 changes: 2 additions & 0 deletions src/compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export { isError } from './predicate/isError.ts';
export { isFinite } from './predicate/isFinite.ts';
export { isTypedArray } from './predicate/isTypedArray.ts';
export { isMatch } from './predicate/isMatch.ts';
export { isMap } from './predicate/isMap.ts';
export { isSet } from './predicate/isSet.ts';
export { isRegExp } from './predicate/isRegExp.ts';
export { isString } from './predicate/isString.ts';
export { matches } from './predicate/matches.ts';
Expand Down
43 changes: 43 additions & 0 deletions src/compat/predicate/isMap.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { describe, expect, it } from 'vitest';
import { isMap } from './isMap';
import { args } from '../_internal/args';
import { falsey } from '../_internal/falsey';
import { slice } from '../_internal/slice';
import { stubFalse } from '../_internal/stubFalse';
import { symbol } from '../_internal/symbol';
import { weakMap } from '../_internal/weakMap';

describe('isMap', () => {
it('should return `true` for maps', () => {
expect(isMap(new Map())).toBe(true);
});

it('returns false if the value is not a Map', () => {
const expected = falsey.map(() => stubFalse());

const actual = falsey.map((value, index) => (index ? isMap(value) : isMap()));

expect(actual).toEqual(expected);

expect(isMap(args)).toBe(false);
expect(isMap([1, 2, 3])).toBe(false);
expect(isMap(true)).toBe(false);
expect(isMap(new Date())).toBe(false);
expect(isMap(new Error())).toBe(false);
expect(isMap(slice)).toBe(false);
expect(isMap({ a: 1 })).toBe(false);
expect(isMap(1)).toBe(false);
expect(isMap(/x/)).toBe(false);
expect(isMap('a')).toBe(false);
expect(isMap(symbol)).toBe(false);
expect(isMap(weakMap)).toBe(false);
});

it('should work for objects with a non-function `constructor` (test in IE 11)', () => {
const expected = falsey.map(() => stubFalse());

const actual = falsey.map(value => isMap({ constructor: value }));

expect(actual).toEqual(expected);
});
});
23 changes: 23 additions & 0 deletions src/compat/predicate/isMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isMap as isMapToolKit } from '../../predicate';

/**
* Checks if a given value is `Map`.
*
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Map`.
*
* @param {unknown} value The value to check if it is a `Map`.
* @returns {value is Map<any, any>} Returns `true` if `value` is a `Map`, else `false`.
*
* @example
* const value1 = new Map();
* const value2 = new Set();
* const value3 = new WeakMap();
*
* console.log(isMap(value1)); // true
* console.log(isMap(value2)); // false
* console.log(isMap(value3)); // false
*/

export function isMap(value?: unknown): value is Map<any, any> {
return isMapToolKit(value);
}
43 changes: 43 additions & 0 deletions src/compat/predicate/isSet.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { describe, expect, it } from 'vitest';
import { isSet } from './isSet';
import { args } from '../_internal/args';
import { falsey } from '../_internal/falsey';
import { slice } from '../_internal/slice';
import { stubFalse } from '../_internal/stubFalse';
import { symbol } from '../_internal/symbol';
import { weakSet } from '../_internal/weakSet';

describe('isSet', () => {
it('should return `true` for sets', () => {
expect(isSet(new Set())).toBe(true);
});

it('should return `false` for non-sets', () => {
const expected = falsey.map(() => stubFalse());

const actual = falsey.map((value, index) => (index ? isSet(value) : isSet()));

expect(actual).toEqual(expected);

expect(isSet(args)).toBe(false);
expect(isSet([1, 2, 3])).toBe(false);
expect(isSet(true)).toBe(false);
expect(isSet(new Date())).toBe(false);
expect(isSet(new Error())).toBe(false);
expect(isSet(slice)).toBe(false);
expect(isSet({ a: 1 })).toBe(false);
expect(isSet(1)).toBe(false);
expect(isSet(/x/)).toBe(false);
expect(isSet('a')).toBe(false);
expect(isSet(symbol)).toBe(false);
expect(isSet(weakSet)).toBe(false);
});

it('should work for objects with a non-function `constructor` (test in IE 11)', () => {
const expected = falsey.map(() => stubFalse());

const actual = falsey.map(value => isSet({ constructor: value }));

expect(actual).toEqual(expected);
});
});
23 changes: 23 additions & 0 deletions src/compat/predicate/isSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isSet as isSetToolkit } from '../../predicate/isSet.ts';

/**
* Checks if a given value is `Set`.
*
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Set`.
*
* @param {unknown} value The value to check if it is a `Set`.
* @returns {value is Set<any>} Returns `true` if `value` is a `Set`, else `false`.
*
* @example
* const value1 = new Set();
* const value2 = new Map();
* const value3 = new WeakSet();
*
* console.log(isSet(value1)); // true
* console.log(isSet(value2)); // false
* console.log(isSet(value3)); // false
*/

export function isSet(value?: unknown): value is Set<any> {
return isSetToolkit(value);
}

0 comments on commit 57155d7

Please sign in to comment.