Repository: marpple/FxTS
Pull request #315 (2025-04-02 13:26:41)

feat: add `head` to `fx`
add `head` to `fx`


Patch:
diff --git a/src/Lazy/fx.ts b/src/Lazy/fx.ts
index ebe4e532..2fb7d542 100644
--- a/src/Lazy/fx.ts
+++ b/src/Lazy/fx.ts
@@ -5,6 +5,7 @@ import every from "../every";
 import find from "../find";
 import findIndex from "../findIndex";
 import groupBy from "../groupBy";
+import head from "../head";
 import indexBy from "../indexBy";
 import isUndefined from "../isUndefined";
 import join from "../join";
@@ -333,6 +334,16 @@ class FxAsyncIterable<A> {
     return each(f, this.asyncIterable);
   }
 
+  /**
+   * Returns the first element of Iterable/AsyncIterable.
+   * It works the same way as `head`.
+   *
+   * see {@link https://fxts.dev/docs/head | head}
+   */
+  async head(): Promise<A | undefined> {
+    return head(this.asyncIterable);
+  }
+
   /**
    * Takes item from AsyncIterable and returns an array.
    *
@@ -638,6 +649,16 @@ export class FxIterable<A> {
     return each(f, this.iterable);
   }
 
+  /**
+   * Returns the first element of Iterable/AsyncIterable.
+   * It works the same way as `head`.
+   *
+   * see {@link https://fxts.dev/docs/head | head}
+   */
+  head(): A | undefined {
+    return head(this.iterable);
+  }
+
   /**
    * Takes item from Iterable and returns an array.
    *


Test patch:
diff --git a/test/head.spec.ts b/test/head.spec.ts
index 8be4627d..52d7c469 100644
--- a/test/head.spec.ts
+++ b/test/head.spec.ts
@@ -1,5 +1,5 @@
 import { filter, head, map, pipe, toAsync } from "../src";
-import { range } from "../src/Lazy";
+import { fx, range } from "../src/Lazy";
 
 describe("head", function () {
   describe("sync", function () {
@@ -27,6 +27,14 @@ describe("head", function () {
       );
       expect(res1).toEqual(12);
     });
+
+    it("should be able to be used as a chaining method in the `fx`", function () {
+      const res1 = fx([1, 2, 3]).head();
+      expect(res1).toEqual(1);
+
+      const res2 = fx([]).head();
+      expect(res2).toEqual(undefined);
+    });
   });
 
   describe("async", function () {
@@ -43,5 +51,13 @@ describe("head", function () {
       );
       expect(res).toEqual(12);
     });
+
+    it("should be able to be used as a chaining method in the `fx`", async function () {
+      const res1 = await fx([1, 2, 3]).toAsync().head();
+      expect(res1).toEqual(1);
+
+      const res2 = await fx([]).toAsync().head();
+      expect(res2).toEqual(undefined);
+    });
   });
 });
diff --git a/type-check/head.test.ts b/type-check/head.test.ts
index 66b7a927..81c6f1cd 100644
--- a/type-check/head.test.ts
+++ b/type-check/head.test.ts
@@ -1,4 +1,4 @@
-import { head, pipe, toAsync } from "../src";
+import { fx, head, pipe, toAsync } from "../src";
 import * as Test from "../src/types/Test";
 
 const { checks, check } = Test;
@@ -15,6 +15,7 @@ const res5 = pipe([1, 2, 3], toAsync, head);
 const res6 = head([] as const);
 const res7 = head([1] as const);
 const res8 = head([1, "2"] as const);
+const res9 = fx([1, 2]).head();
 
 checks([
   check<typeof res1, undefined, Test.Pass>(),
@@ -27,4 +28,5 @@ checks([
   check<typeof res6, undefined, Test.Pass>(),
   check<typeof res7, 1, Test.Pass>(),
   check<typeof res8, 1, Test.Pass>(),
+  check<typeof res9, number | undefined, Test.Pass>(),
 ]);