Repository: marpple/FxTS (ts)

Issue:
Type Inference issue when using `prop` with `indexBy`
When using the `prop` function together with `indexBy`, type inference does not work correctly.

Is this the intended behavior?

```ts
const users = pipe(
  [
    { name: "a", email: "a@a.com" },
    { name: "b", email: "b@b.com" },
    { name: "c", email: "c@c.com" },
  ],
  indexBy(prop("name")),
)

// const users: {}
```

```ts
const users = pipe(
  [
    { name: "a", email: "a@a.com" },
    { name: "b", email: "b@b.com" },
    { name: "c", email: "c@c.com" },
  ],
  indexBy((n) => n.name),
)

// const users: {
//     [x: string]: {
//         name: string;
//         email: string;
//     } & {};
// }
```

```ts
const users = pipe(
  [
    { name: "a", email: "a@a.com" },
    { name: "b", email: "b@b.com" },
    { name: "c", email: "c@c.com" },
  ],
  indexBy((n) => props("name")(n)),
)

// const users: {
//     [x: string]: {
//         name: string;
//         email: string;
//     } & {};
// }
```

Pull request description:
fix: type inference to work correctly
Fixes #308 

Please let me know if you have any problems:)


Patch:
diff --git a/src/prop.ts b/src/prop.ts
index 2f0db95c..47684bc0 100644
--- a/src/prop.ts
+++ b/src/prop.ts
@@ -27,7 +27,9 @@ type Prop<T, K extends Key> = T extends null
  * ```
  */
 function prop<K extends Key, T>(key: K, obj: T): Prop<T, K>;
-function prop<K extends Key>(key: K): <T>(obj: T) => Prop<T, K>;
+function prop<K extends Key>(
+  key: K,
+): <T extends Record<Key, any> | null>(obj: T) => Prop<T, K>;
 
 function prop<K extends Key, T>(key: K, obj?: T) {
   if (obj === null) return undefined;


Test patch:
diff --git a/test/prop.spec.ts b/test/prop.spec.ts
index 36a5b9ff..abc581be 100644
--- a/test/prop.spec.ts
+++ b/test/prop.spec.ts
@@ -7,6 +7,7 @@ describe("prop", () => {
     expect(prop("a", obj)).toBe(1);
     expect(prop("b", obj)).toBe("2");
     expect(prop("c", obj)).toBe(undefined);
+    expect(prop("d", null)).toBe(undefined);
   });
 
   it("should be able to operate on arrays", () => {
diff --git a/type-check/prop.test.ts b/type-check/prop.test.ts
index 8a5ac379..b7e106cb 100644
--- a/type-check/prop.test.ts
+++ b/type-check/prop.test.ts
@@ -1,4 +1,4 @@
-import { map, pipe, prop, toArray } from "../src";
+import { indexBy, map, pipe, prop, toArray } from "../src";
 import * as Test from "../src/types/Test";
 
 const { checks, check } = Test;
@@ -24,6 +24,7 @@ const res11 = pipe(
   map(prop("str")),
   toArray,
 );
+const res12 = pipe([{ str: "foo" }, { str: "bar" }], indexBy(prop("str")));
 
 checks([
   check<typeof res1, "value", Test.Pass>(),
@@ -37,4 +38,5 @@ checks([
   check<typeof res9, number, Test.Pass>(),
   check<typeof res10, string, Test.Pass>(),
   check<typeof res11, string[], Test.Pass>(),
+  check<typeof res12, { [x: string]: { str: string } }, Test.Pass>(),
 ]);