Repository: marpple/FxTS (ts)

Issue:
bug: `join` If one numeric parameter is entered, it is returned as number type rather than string.
# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 💻 Code

<!-- Please post the relevant code sample here as well-->
<!-- How to reproduce it -->

```ts
const res = join("-", [1]);
console.log("res", res); // number type
```

### 🙁 Actual behavior

<!-- What happened, and why it was wrong -->

we expect number type

### 🙂 Expected behavior

<!-- What you expected to happen instead, and why -->

come string type

---

### Version Information

<!-- Please let me know your environment -->

- Operating system:
- Typescript:
- Nodejs:


Pull request description:
fix: join when parameter is number
Fixes #226


Patch:
diff --git a/src/join.ts b/src/join.ts
index 206f5d53..f51282c4 100644
--- a/src/join.ts
+++ b/src/join.ts
@@ -1,4 +1,5 @@
 import { isAsyncIterable, isIterable } from "./_internal/utils";
+import isString from "./isString";
 import reduce from "./reduce";
 
 type ReturnJoinType<T extends Iterable<unknown> | AsyncIterable<unknown>> =
@@ -9,13 +10,22 @@ type ReturnJoinType<T extends Iterable<unknown> | AsyncIterable<unknown>> =
     : never;
 
 function sync<A>(sep: string, iterable: Iterable<A>) {
-  return reduce((a: string, b) => `${a}${sep}${b}`, iterable) ?? "";
+  const res = reduce((a: string, b) => `${a}${sep}${b}`, iterable);
+  if (res == null) {
+    return "";
+  }
+
+  return isString(res) ? res : String(res);
 }
 
 function async<A>(sep: string, iterable: AsyncIterable<A>) {
-  return reduce((a: string, b) => `${a}${sep}${b}`, iterable).then(
-    (a) => a ?? "",
-  );
+  return reduce((a: string, b) => `${a}${sep}${b}`, iterable).then((res) => {
+    if (res == null) {
+      return "";
+    }
+
+    return isString(res) ? res : String(res);
+  });
 }
 
 /**
diff --git a/website/docs_md/getting-started.md b/website/docs_md/getting-started.md
index 138f069a..2f2ba647 100644
--- a/website/docs_md/getting-started.md
+++ b/website/docs_md/getting-started.md
@@ -51,7 +51,7 @@ const sum = pipe(
 ); // typeof 'sum' inferred as the number
 ```
 
-**Note: It is recommended to enable [strictFunctionTypes](https://www.typescriptlang.org/tsconfig#strictFunctionTypes) tsc option. If not, type inference does not work as we expected. For example, in the example above, `sum` is not inferred as a number type if the option is turned off.**
+**Note: It is recommended to enable [strictFunctionTypes](https://www.typescriptlang.org/tsconfig#strictFunctionTypes), [strictNullChecks](https://www.typescriptlang.org/tsconfig#strictNullChecks) tsc option. If not, type inference does not work as we expected. For example, in the example above, `sum` is not inferred as a number type if the option is turned off.**
 
 ### JavaScript
 


Test patch:
diff --git a/test/join.spec.ts b/test/join.spec.ts
index 58b3d2ab..de7e86a9 100644
--- a/test/join.spec.ts
+++ b/test/join.spec.ts
@@ -10,6 +10,7 @@ describe("join", function () {
     });
 
     it("should be joined with separator", function () {
+      expect(join("_", [1])).toEqual("1");
       expect(join(", ", "hello")).toEqual("h, e, l, l, o");
     });
 
diff --git a/type-check/join.test.ts b/type-check/join.test.ts
index 44f7ea3a..a739a01c 100644
--- a/type-check/join.test.ts
+++ b/type-check/join.test.ts
@@ -3,14 +3,16 @@ import * as Test from "../src/types/Test";
 
 const { checks, check } = Test;
 
-const res1 = join("-", []);
+const res0 = join("-", []);
+const res1 = join("-", [1]);
 const res2 = join("!", [1, 2, 3, 4]);
 const res3 = join("*", toAsync([1, 2, 3, 4]));
 const res4 = pipe([1, 2, 3, 4], join("-"));
 const res5 = pipe(toAsync([1, 2, 3, 4]), join("#"));
 
 checks([
-  check<typeof res1, "", Test.Pass>(),
+  check<typeof res0, "", Test.Pass>(),
+  check<typeof res1, string, Test.Pass>(),
   check<typeof res2, string, Test.Pass>(),
   check<typeof res3, Promise<string>, Test.Pass>(),
   check<typeof res4, string, Test.Pass>(),