Repository: marpple/FxTS (ts)

Issue:
Add `isNil` function
# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## ⭐ Suggestion

<!-- What would you like to be added? -->

Checks if the given value is `null` or `undefined`.

## 💻 Use Cases

<!-- What do you want to use this for? -->
```
isNil(1); // false
isNil('1'); // false
isNil(undefined); // true
isNil(null); // true
```

Pull request description:
feat: add `isNil` function
Fixes #43


Patch:
diff --git a/src/index.ts b/src/index.ts
index f0f62157..a0b2cf40 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -8,6 +8,7 @@ import head from "./head";
 import identity from "./identity";
 import indexBy from "./indexBy";
 import isArray from "./isArray";
+import isNil from "./isNil";
 import isString from "./isString";
 import join from "./join";
 import last from "./last";
@@ -34,6 +35,7 @@ export {
   identity,
   indexBy,
   isArray,
+  isNil,
   isString,
   join,
   last,
diff --git a/src/isNil.ts b/src/isNil.ts
new file mode 100644
index 00000000..78ce7caa
--- /dev/null
+++ b/src/isNil.ts
@@ -0,0 +1,20 @@
+type Nullable<T> = T extends null | undefined ? T : never;
+
+/**
+ * Checks if the given value is `null` or `undefined`.
+ *
+ * @example
+ * isNil(1); // false
+ * isNil('1'); // false
+ * isNil(undefined); // true
+ * isNil(null); // true
+ */
+function isNil<T>(a: T): a is Nullable<T> {
+  if (a === undefined || a === null) {
+    return true;
+  }
+
+  return false;
+}
+
+export default isNil;


Test patch:
diff --git a/test/isNil.spec.ts b/test/isNil.spec.ts
new file mode 100644
index 00000000..2117afbc
--- /dev/null
+++ b/test/isNil.spec.ts
@@ -0,0 +1,26 @@
+import { isNil } from "../src/index";
+
+describe("isNil", function () {
+  it("should check if given value is `null` or `undefined`", function () {
+    const res1 = isNil(null);
+    expect(res1).toEqual(true);
+
+    const res2 = isNil(undefined);
+    expect(res2).toEqual(true);
+
+    const res3 = isNil(3);
+    expect(res3).toEqual(false);
+
+    const res4 = isNil("3");
+    expect(res4).toEqual(false);
+
+    const res5 = isNil({});
+    expect(res5).toEqual(false);
+
+    const res6 = isNil(Symbol("3"));
+    expect(res6).toEqual(false);
+
+    const res7 = isNil(false);
+    expect(res7).toEqual(false);
+  });
+});
diff --git a/type-check/isNil.test.ts b/type-check/isNil.test.ts
new file mode 100644
index 00000000..561cc415
--- /dev/null
+++ b/type-check/isNil.test.ts
@@ -0,0 +1,29 @@
+import * as Test from "../src/types/Test";
+import { isNil, map, pipe, toArray } from "../src";
+
+const { checks, check } = Test;
+
+type User = {
+  name?: string | null;
+  age: number;
+};
+
+const user: User = {
+  age: 23,
+};
+
+function getUserName(user: User) {
+  if (!isNil(user.name)) {
+    return user.name;
+  }
+
+  throw new Error("Not exist user's name");
+}
+
+const res1 = getUserName(user);
+const res2 = pipe([user, user, user], map(getUserName), toArray);
+
+checks([
+  check<typeof res1, string, Test.Pass>(),
+  check<typeof res2, string[], Test.Pass>(),
+]);