From cd4aba143c3fa1ce734b7f6db44a7f56e4080aed Mon Sep 17 00:00:00 2001
From: Matei Adriel <rafaeladriel11@gmail.com>
Date: Wed, 25 Dec 2019 15:17:22 +0200
Subject: [PATCH] typescript(option): feat: added an optionify helper

Signed-off-by: prescientmoon <git@moonythm.dev>
---
 typescript/option/src/helpers/external.ts       |  1 +
 typescript/option/src/helpers/optionify.test.ts | 17 +++++++++++++++++
 typescript/option/src/helpers/optionify.ts      | 15 +++++++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 typescript/option/src/helpers/optionify.test.ts
 create mode 100644 typescript/option/src/helpers/optionify.ts

diff --git a/typescript/option/src/helpers/external.ts b/typescript/option/src/helpers/external.ts
index e2c7a4e..7152985 100644
--- a/typescript/option/src/helpers/external.ts
+++ b/typescript/option/src/helpers/external.ts
@@ -15,6 +15,7 @@ export * from './isSome'
 export * from './iter'
 export * from './map'
 export * from './mapAsync'
+export * from './optionify'
 export * from './toArray'
 export * from './toNullable'
 export * from './withDefault'
diff --git a/typescript/option/src/helpers/optionify.test.ts b/typescript/option/src/helpers/optionify.test.ts
new file mode 100644
index 0000000..04e6e9e
--- /dev/null
+++ b/typescript/option/src/helpers/optionify.test.ts
@@ -0,0 +1,17 @@
+import { expect } from 'chai'
+import { optionify } from './optionify'
+import { fromNullable } from './fromNullable'
+
+describe('The optionify helper', () => {
+    it('should create a function which returns an option instead of a nullable', () => {
+        // arrange
+        const func = (a: number, b: number) => (a > b ? a + b : null)
+
+        // act
+        const result = optionify(func)
+
+        // assert
+        expect(result(1, 2)).to.equal(fromNullable(func(1, 2)))
+        expect(result(2, 1)).to.equal(fromNullable(func(2, 1)))
+    })
+})
diff --git a/typescript/option/src/helpers/optionify.ts b/typescript/option/src/helpers/optionify.ts
new file mode 100644
index 0000000..d617f30
--- /dev/null
+++ b/typescript/option/src/helpers/optionify.ts
@@ -0,0 +1,15 @@
+import { fromNullable } from './fromNullable'
+
+/**
+ * Takes a function which returns a nullable and creates
+ * a function which returns an Option.
+ * In functional programming this would be the same as
+ * composing the function with fromNullable.
+ *
+ * @param f The function to optionify
+ */
+export const optionify = <T extends unknown[], U>(
+    f: (...args: T) => U | null
+) => {
+    return (...args: T) => fromNullable(f(...args))
+}