Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isNullish, isNonNullish and isKeyOf Utility Functions #385

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cdn/radash.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ const isEqual = (x, y) => {
}
return true;
};
const isNullish = (value) => {
return value === null || value === void 0;
};
const isNonNullish = (value) => {
return value !== null && value !== void 0;
};
const isKeyOf = (value, obj) => {
return value in obj;
};

const group = (array, getGroupId) => {
return array.reduce((acc, item) => {
Expand Down Expand Up @@ -937,4 +946,4 @@ const trim = (str, charsToTrim = " ") => {
return str.replace(regex, "");
};

export { all, alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, guard, inRange, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isPromise, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject };
export { all, alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, guard, inRange, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isKeyOf, isNonNullish, isNullish, isNumber, isObject, isPrimitive, isPromise, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject };
12 changes: 12 additions & 0 deletions cdn/radash.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ var radash = (function (exports) {
}
return true;
};
const isNullish = (value) => {
return value === null || value === void 0;
};
const isNonNullish = (value) => {
return value !== null && value !== void 0;
};
const isKeyOf = (value, obj) => {
return value in obj;
};

const group = (array, getGroupId) => {
return array.reduce((acc, item) => {
Expand Down Expand Up @@ -975,6 +984,9 @@ var radash = (function (exports) {
exports.isFloat = isFloat;
exports.isFunction = isFunction;
exports.isInt = isInt;
exports.isKeyOf = isKeyOf;
exports.isNonNullish = isNonNullish;
exports.isNullish = isNullish;
exports.isNumber = isNumber;
exports.isObject = isObject;
exports.isPrimitive = isPrimitive;
Expand Down
2 changes: 1 addition & 1 deletion cdn/radash.min.js

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions docs/typed/is-key-of.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: isKeyOf
description: 'Checks if the given value is a key of the given object. It is useful for narrowing down the type of a value.'
group: Typed
---

## Basic usage

Pass the object and the value to check. It will return a boolean indicating if the value is a key of the object.

```ts
import { isKeyOf } from 'radash'

const obj = {
a: 1,
b: 2,
c: 3,
}
isKeyOf(obj, 'a') // true
isKeyOf(obj, 'd') // false
```
23 changes: 23 additions & 0 deletions docs/typed/is-non-nullish.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: isNonNullish
description: 'Checks if the given value is not null or undefined.'
group: Typed
---

## Basic usage

Pass in a value and get a boolean telling you if the value is not a Nullish.

```ts
import { isNonNullish } from 'radash'

isNonNullish(null) // false
isNonNullish(undefined) // false
isNonNullish('') // true
isNonNullish(0) // true
isNonNullish(false) // true
isNonNullish(NaN) // true
isNonNullish([]) // true
isNonNullish({}) // true

```
22 changes: 22 additions & 0 deletions docs/typed/is-nullish.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: isNullish
description: 'Checks if the given value is null or undefined.'
group: Typed
---

## Basic usage

Pass in a value and get a boolean telling you if the value is a Nullish.

```ts
import { isNullish } from 'radash'

isNullish(null) // true
isNullish(undefined) // true
isNullish(0) // false
isNullish('') // false
isNullish(false) // false
isNullish(NaN) // false
isNullish([]) // false
isNullish({}) // false
```
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ export {
isFloat,
isFunction,
isInt,
isKeyOf,
isNonNullish,
isNullish,
isNumber,
isObject,
isPrimitive,
Expand Down
47 changes: 47 additions & 0 deletions src/tests/typed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,4 +541,51 @@ describe('typed module', () => {
assert.isFalse(_.isEqual([complex], [{ ...complex, num: 222 }]))
})
})

describe('isNullish function', () => {
test('returns true for null and undefined', () => {
assert.isTrue(_.isNullish(null))
assert.isTrue(_.isNullish(undefined))
})
test('returns false for non-nullish values', () => {
assert.isFalse(_.isNullish(0))
assert.isFalse(_.isNullish(''))
assert.isFalse(_.isNullish(false))
assert.isFalse(_.isNullish([]))
assert.isFalse(_.isNullish({}))
assert.isFalse(_.isNullish(() => {}))
assert.isFalse(_.isNullish(Symbol('')))
assert.isFalse(_.isNullish(new Date()))
})
})

describe('isNonNullish function', () => {
test('returns false for null and undefined', () => {
assert.isFalse(_.isNonNullish(null))
assert.isFalse(_.isNonNullish(undefined))
})
test('returns true for non-nullish values', () => {
assert.isTrue(_.isNonNullish(0))
assert.isTrue(_.isNonNullish(''))
assert.isTrue(_.isNonNullish(false))
assert.isTrue(_.isNonNullish([]))
assert.isTrue(_.isNonNullish({}))
assert.isTrue(_.isNonNullish(() => {}))
assert.isTrue(_.isNonNullish(Symbol('')))
assert.isTrue(_.isNonNullish(new Date()))
})
})

describe('isKeyOf function', () => {
test('returns true for keys of the object', () => {
const obj = { name: 'ray', age: 22 }
assert.isTrue(_.isKeyOf('name', obj))
assert.isTrue(_.isKeyOf('age', obj))
})
test('returns false for keys not in the object', () => {
const obj = { name: 'ray', age: 22 }
assert.isFalse(_.isKeyOf('height', obj))
assert.isFalse(_.isKeyOf('weight', obj))
})
})
})
29 changes: 29 additions & 0 deletions src/typed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,32 @@ export const isEqual = <TType>(x: TType, y: TType): boolean => {
}
return true
}

/**
* Checks if the given value is null or undefined.
*/
export const isNullish = (value: any): value is null | undefined => {
return value === null || value === undefined
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not having this is by-design? Why not value == null or value != null instead?

}

/**
* Checks if the given value is not null or undefined.
*/
export const isNonNullish = <TType>(
value: TType
): value is Exclude<TType, null | undefined> => {
return value !== null && value !== undefined
}

/**
* Checks if the given value is a key of the given object. It is useful for narrowing down the type of a value.
* @param value key to check
* @param obj object to check
* @returns true if the value is a key of the object
*/
export const isKeyOf = <TType extends Record<string | number | symbol, any>>(
value: string | number | symbol,
obj: TType
): value is keyof TType => {
return value in obj
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal with Radash is to provide the powerful functions you need, not the ones the runtimes now provide

This feels like it goes against the library's philosophy. You can easily do value in obj yourself or use Object.hasOwn (which are different)

Also, I half-expect this to match Object.hasOwn, that is, isKeyOf({}, "toString") to be false

}
Loading