Repository: true-myth/true-myth
Pull request #1009 (2025-04-14 22:50:33)

bug: fix `maybe.get` types
Add some coverage. Additionally, fix the name of one of the test suites. Noticed while working on fixes for #994.


Patch:
diff --git a/src/maybe.ts b/src/maybe.ts
index 6861cd6..77e902c 100644
--- a/src/maybe.ts
+++ b/src/maybe.ts
@@ -1467,9 +1467,14 @@ export function property<T, K extends keyof T>(
   @param key The key to pull out of the object.
   @param maybeObj The object to look up the key from.
  */
-export function get<T, K extends keyof T>(key: K, maybeObj: Maybe<T>): Maybe<NonNullable<T[K]>>;
-export function get<T, K extends keyof T>(key: K): (maybeObj: Maybe<T>) => Maybe<NonNullable<T[K]>>;
-export function get<T, K extends keyof T>(
+export function get<T extends { [key: string]: unknown }, K extends keyof T>(
+  key: K,
+  maybeObj: Maybe<T>
+): Maybe<NonNullable<T[K]>>;
+export function get<T extends { [key: string]: unknown }, K extends keyof T>(
+  key: K
+): (maybeObj: Maybe<T>) => Maybe<NonNullable<T[K]>>;
+export function get<T extends { [key: string]: unknown }, K extends keyof T>(
   key: K,
   maybeObj?: Maybe<T>
 ): Maybe<NonNullable<T[K]>> | ((maybeObj: Maybe<T>) => Maybe<NonNullable<T[K]>>) {


Test patch:
diff --git a/test/maybe.test.ts b/test/maybe.test.ts
index a4d0058..30e9d98 100644
--- a/test/maybe.test.ts
+++ b/test/maybe.test.ts
@@ -507,19 +507,43 @@ describe('`Maybe` pure functions', () => {
     expect(maybe.property('wat', dict)).toEqual(maybe.nothing());
   });
 
-  test('`get`', () => {
-    type Person = { name?: string };
-    let chris: Person = { name: 'chris' };
-    let justChris: Maybe<Person> = maybe.just(chris);
-    expect(maybe.get('name', justChris)).toEqual(maybe.just('chris'));
+  describe('`get`', () => {
+    test('basic form', () => {
+      type Person = { name?: string };
+      let chris: Person = { name: 'chris' };
+      let justChris: Maybe<Person> = maybe.just(chris);
+      expect(maybe.get('name', justChris)).toEqual(maybe.just('chris'));
+
+      let nobody: Maybe<Person> = maybe.nothing();
+      expect(maybe.get('name', nobody)).toEqual(maybe.nothing());
+
+      type Dict<T> = { [key: string]: T };
+      let dict = maybe.just({ quux: 'warble' } as Dict<string>);
+      expect(maybe.get('quux', dict)).toEqual(maybe.just('warble'));
+      expect(maybe.get('wat', dict)).toEqual(maybe.nothing());
+    });
 
-    let nobody: Maybe<Person> = maybe.nothing();
-    expect(maybe.get('name', nobody)).toEqual(maybe.nothing());
+    test('curried form', () => {
+      type DeepType = { something?: { with?: { deeper?: { 'key names'?: string } } } };
 
-    type Dict<T> = { [key: string]: T };
-    let dict = maybe.just({ quux: 'warble' } as Dict<string>);
-    expect(maybe.get('quux', dict)).toEqual(maybe.just('warble'));
-    expect(maybe.get('wat', dict)).toEqual(maybe.nothing());
+      const allSet: DeepType = { something: { with: { deeper: { 'key names': 'like this' } } } };
+      let fromSet = maybe.get(
+        'key names',
+        maybe.get('deeper', maybe.get('with', maybe.get('something', Maybe.of(allSet))))
+      );
+
+      const allEmpty: DeepType = {};
+      let fromEmpty = maybe.get(
+        'key names',
+        maybe.get('deeper', maybe.get('with', maybe.get('something', Maybe.of(allEmpty))))
+      );
+
+      expect(fromEmpty).toEqual(maybe.nothing());
+
+      expectTypeOf(fromSet).toEqualTypeOf(fromEmpty);
+      expectTypeOf(fromSet).toEqualTypeOf<Maybe<string>>();
+      expectTypeOf(fromEmpty).toEqualTypeOf<Maybe<string>>();
+    });
   });
 
   test('`safe`', () => {
@@ -833,7 +857,7 @@ describe('`Maybe` class', () => {
       expect(result.equals(maybe.of('3'))).toBe(true);
     });
 
-    test('`property` method', () => {
+    test('`get` method', () => {
       type DeepType = { something?: { with?: { deeper?: { 'key names'?: string } } } };
 
       const allSet: DeepType = { something: { with: { deeper: { 'key names': 'like this' } } } };