@alwatr/is-number 5.5.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [5.6.1](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@5.6.0...@alwatr/is-number@5.6.1) (2025-04-01)
7
+
8
+ **Note:** Version bump only for package @alwatr/is-number
9
+
10
+ ## [5.6.0](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@5.5.0...@alwatr/is-number@5.6.0) (2025-03-18)
11
+
12
+ ### Features
13
+
14
+ * **is-number:** add polyfill for Number.isFinite to check finite numbers ([27c60b1](https://github.com/Alwatr/nanolib/commit/27c60b16e69e87fd62dee25ee21012651b9ba7ca)) by @alimd
15
+ * **is-number:** add toNumber function to convert various values to numbers ([3f4a9d1](https://github.com/Alwatr/nanolib/commit/3f4a9d1d316ba685c47cafdee031e231ef0d40c5)) by @alimd
16
+
17
+ ### Code Refactoring
18
+
19
+ * **is-number:** enhance isNumber function to handle additional cases and improve documentation ([16f16b4](https://github.com/Alwatr/nanolib/commit/16f16b41c487f874f94dd64aaa778c618879db82)) by @alimd
20
+
6
21
  ## [5.5.0](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@5.4.0...@alwatr/is-number@5.5.0) (2025-03-06)
7
22
 
8
23
  ### Miscellaneous Chores
package/README.md CHANGED
@@ -1,35 +1,68 @@
1
1
  # is-number
2
2
 
3
- A simple utility to Check the value is number or can convert to a number, for example string ' 123 ' can be converted to 123.
3
+ A lightweight, high-performance utility to check if a value is a number or can be converted to a number.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  yarn add @alwatr/is-number
9
+ # or
10
+ npm install @alwatr/is-number
9
11
  ```
10
12
 
11
13
  ## Usage
12
14
 
13
15
  ```typescript
14
- import {isNumber} from '@alwatr/is-number';
15
-
16
- isNumber('1'); // true
16
+ import {isNumber, toNumber, isFiniteNumber} from '@alwatr/is-number';
17
+
18
+ // Check if a value is a number
19
+ isNumber(123); // true
20
+ isNumber('123'); // true
21
+ isNumber('abc'); // false
22
+
23
+ // Convert a value to a number if possible
24
+ toNumber(123); // 123
25
+ toNumber('123'); // 123
26
+ toNumber('abc'); // null
27
+
28
+ // Check if a value is a finite number (without type coercion)
29
+ isFiniteNumber(123); // true
30
+ isFiniteNumber(Infinity); // false
31
+ isFiniteNumber('123'); // false (no coercion)
17
32
  ```
18
33
 
34
+ ## API
35
+
36
+ ### isNumber(value: unknown): boolean
37
+
38
+ Checks if the value is a number or can be converted to a number.
39
+
40
+ ### toNumber(value: unknown): number | null
41
+
42
+ Converts the value to a number if possible, otherwise returns `null`.
43
+
44
+ ### isFiniteNumber(value: unknown): boolean
45
+
46
+ A cross-browser polyfill for `Number.isFinite`. Unlike the global `isFinite`,
47
+ this doesn't coerce values to numbers before checking.
48
+
19
49
  ## Why is this needed?
20
50
 
51
+ JavaScript type behavior can be confusing. This library helps to simplify number validation:
52
+
21
53
  ```ts
22
- console.log(typeof '123'); //=> 'string'
23
- console.log(+[]); //=> 0
24
- console.log(+''); //=> 0
25
- console.log(+' '); //=> 0
26
- console.log(typeof NaN); //=> 'number'
27
- console.log(typeof Infinity); //=> 'number'
54
+ console.log(typeof '123'); // 'string'
55
+ console.log(+[]); // 0
56
+ console.log(+''); // 0
57
+ console.log(+' '); // 0
58
+ console.log(typeof NaN); // 'number'
59
+ console.log(typeof Infinity); // 'number'
28
60
  ```
29
61
 
30
- ### True
62
+ ### isNumber Examples
63
+
64
+ #### Returns `true`
31
65
 
32
- <!-- prettier-ignore -->
33
66
  ```ts
34
67
  isNumber(5e3); // true
35
68
  isNumber(0xff); // true
@@ -44,13 +77,11 @@ isNumber('1'); // true
44
77
  isNumber('1.1'); // true
45
78
  isNumber('5e3'); // true
46
79
  isNumber('012'); // true
47
- isNumber(parseInt('012')); // true
48
- isNumber(parseFloat('012')); // true
80
+ isNumber(' 123 '); // true
49
81
  ```
50
82
 
51
- ### False
83
+ #### Returns `false`
52
84
 
53
- <!-- prettier-ignore -->
54
85
  ```ts
55
86
  isNumber(Infinity); // false
56
87
  isNumber(NaN); // false
@@ -59,12 +90,47 @@ isNumber(undefined); // false
59
90
  isNumber(''); // false
60
91
  isNumber(' '); // false
61
92
  isNumber('foo'); // false
93
+ isNumber('123foo'); // false
62
94
  isNumber([1]); // false
63
95
  isNumber([]); // false
64
96
  isNumber(function () {}); // false
65
97
  isNumber({}); // false
66
98
  ```
67
99
 
100
+ ### toNumber Examples
101
+
102
+ #### Returns a number
103
+
104
+ ```ts
105
+ toNumber(5e3); // 5000
106
+ toNumber(0xff); // 255
107
+ toNumber(-1.1); // -1.1
108
+ toNumber(0); // 0
109
+ toNumber(1); // 1
110
+ toNumber('-1.1'); // -1.1
111
+ toNumber('0'); // 0
112
+ toNumber('0xff'); // 255
113
+ toNumber('5e3'); // 5000
114
+ toNumber(' 123 '); // 123
115
+ ```
116
+
117
+ #### Returns `null`
118
+
119
+ ```ts
120
+ toNumber(Infinity); // null
121
+ toNumber(NaN); // null
122
+ toNumber(null); // null
123
+ toNumber(undefined); // null
124
+ toNumber(''); // null
125
+ toNumber(' '); // null
126
+ toNumber('foo'); // null
127
+ toNumber('123foo'); // null
128
+ toNumber([1]); // null
129
+ toNumber([]); // null
130
+ toNumber(function () {}); // null
131
+ toNumber({}); // null
132
+ ```
133
+
68
134
  ## Sponsors
69
135
 
70
136
  The following companies, organizations, and individuals support Nanolib ongoing maintenance and development. Become a Sponsor to get your logo on our README and website.
package/dist/main.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/is-number v5.5.0 */
1
+ /* @alwatr/is-number v5.6.1 */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -21,22 +21,47 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/main.ts
22
22
  var main_exports = {};
23
23
  __export(main_exports, {
24
- isNumber: () => isNumber
24
+ isFiniteNumber: () => isFiniteNumber,
25
+ isNumber: () => isNumber,
26
+ toNumber: () => toNumber
25
27
  });
26
28
  module.exports = __toCommonJS(main_exports);
27
29
  var import_package_tracer = require("@alwatr/package-tracer");
28
- __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/is-number", "5.5.0");
30
+ __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/is-number", "5.6.1");
31
+ function isFiniteNumber(value) {
32
+ if (typeof Number.isFinite === "function") {
33
+ return Number.isFinite(value);
34
+ }
35
+ return typeof value === "number" && isFinite(value);
36
+ }
29
37
  function isNumber(value) {
30
38
  if (typeof value === "number") {
31
39
  return value - value === 0;
32
40
  }
33
- if (typeof value === "string" && value.trim() !== "") {
34
- return Number.isFinite ? Number.isFinite(+value) : isFinite(+value);
41
+ if (typeof value === "string") {
42
+ const trimmed = value.trim();
43
+ if (trimmed === "") return false;
44
+ const num = +trimmed;
45
+ return isFiniteNumber(num);
35
46
  }
36
47
  return false;
37
48
  }
49
+ function toNumber(value) {
50
+ if (typeof value === "number") {
51
+ return value - value === 0 ? value : null;
52
+ }
53
+ if (typeof value === "string") {
54
+ const trimmed = value.trim();
55
+ if (trimmed === "") return null;
56
+ const num = +trimmed;
57
+ return isFiniteNumber(num) ? num : null;
58
+ }
59
+ return null;
60
+ }
38
61
  // Annotate the CommonJS export names for ESM import in node:
39
62
  0 && (module.exports = {
40
- isNumber
63
+ isFiniteNumber,
64
+ isNumber,
65
+ toNumber
41
66
  });
42
67
  //# sourceMappingURL=main.cjs.map
package/dist/main.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Check the value is number or can convert to a number, for example string ' 123 ' can be converted to 123\n *\n * @param value - the value must check numeric.\n *\n * @return true if the value is number or can convert to a number, otherwise false.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * isNumber('123'); // true\n * isNumber(' 123 '); // true\n * isNumber(''); // false\n * isNumber(' '); // false\n * isNumber(' 123a '); // false\n * isNumber(' 123 a '); // false\n * ```\n */\nexport function isNumber(value: unknown): boolean {\n if (typeof value === 'number') {\n return value - value === 0;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n return Number.isFinite ? Number.isFinite(+value) : isFinite(+value);\n }\n return false;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4B;AAE5B,aAAc,qCAAc,IAAI,qBAAkB,OAAmB;AAoB9D,SAAS,SAAS,OAAyB;AAChD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU;AAAA,EAC3B;AACA,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,WAAO,OAAO,WAAW,OAAO,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK;AAAA,EACpE;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Polyfill for Number.isFinite - properly checks if a value is a finite number\n * without type coercion.\n *\n * @param value - The value to check\n * @returns true if the value is a finite number, false otherwise\n */\nexport function isFiniteNumber(value: unknown): boolean {\n // Use native implementation if available\n if (typeof Number.isFinite === 'function') {\n return Number.isFinite(value);\n }\n // Fallback implementation\n return typeof value === 'number' && isFinite(value);\n}\n\n/**\n * Check if the value is a number or can be converted to a number.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a number or can be converted to a number, otherwise `false`.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * isNumber('123'); // true\n * isNumber(' 123 '); // true\n * isNumber('0xff'); // true\n * isNumber('-1.1'); // true\n * isNumber(''); // false\n * isNumber(' '); // false\n * isNumber(' 123a '); // false\n * isNumber(NaN); // false\n * isNumber(Infinity); // false\n * isNumber({}); // false\n * isNumber([]); // false\n * isNumber(null); // false\n * isNumber(undefined); // false\n * ```\n */\nexport function isNumber(value: unknown): boolean {\n // Handle number type\n if (typeof value === 'number') {\n return value - value === 0;\n }\n\n // Handle string type\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return false;\n\n // Use unary plus for fastest string-to-number conversion\n const num = +trimmed;\n return isFiniteNumber(num);\n }\n\n return false;\n}\n\n/**\n * Convert a value to a number if possible.\n *\n * @param value - The value to convert.\n * @returns The converted number if valid, otherwise `null`.\n *\n * @example\n * ```ts\n * toNumber(123); // 123\n * toNumber('123'); // 123\n * toNumber(' 123 '); // 123\n * toNumber('0xff'); // 255\n * toNumber('-1.1'); // -1.1\n * toNumber(''); // null\n * toNumber(' '); // null\n * toNumber('123a'); // null\n * toNumber(NaN); // null\n * toNumber(Infinity); // null\n * toNumber({}); // null\n * toNumber([]); // null\n * toNumber(null); // null\n * toNumber(undefined); // null\n * ```\n */\nexport function toNumber(value: unknown): number | null {\n // Handle number type\n if (typeof value === 'number') {\n return value - value === 0 ? value : null;\n }\n\n // Handle string type\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n\n const num = +trimmed;\n return isFiniteNumber(num) ? num : null;\n }\n\n return null;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4B;AAE5B,aAAc,qCAAc,IAAI,qBAAkB,OAAmB;AAS9D,SAAS,eAAe,OAAyB;AAEtD,MAAI,OAAO,OAAO,aAAa,YAAY;AACzC,WAAO,OAAO,SAAS,KAAK;AAAA,EAC9B;AAEA,SAAO,OAAO,UAAU,YAAY,SAAS,KAAK;AACpD;AA0BO,SAAS,SAAS,OAAyB;AAEhD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU;AAAA,EAC3B;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO;AAG3B,UAAM,MAAM,CAAC;AACb,WAAO,eAAe,GAAG;AAAA,EAC3B;AAEA,SAAO;AACT;AA0BO,SAAS,SAAS,OAA+B;AAEtD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU,IAAI,QAAQ;AAAA,EACvC;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO;AAE3B,UAAM,MAAM,CAAC;AACb,WAAO,eAAe,GAAG,IAAI,MAAM;AAAA,EACrC;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/dist/main.d.ts CHANGED
@@ -1,20 +1,59 @@
1
1
  /**
2
- * Check the value is number or can convert to a number, for example string ' 123 ' can be converted to 123
2
+ * Polyfill for Number.isFinite - properly checks if a value is a finite number
3
+ * without type coercion.
3
4
  *
4
- * @param value - the value must check numeric.
5
+ * @param value - The value to check
6
+ * @returns true if the value is a finite number, false otherwise
7
+ */
8
+ export declare function isFiniteNumber(value: unknown): boolean;
9
+ /**
10
+ * Check if the value is a number or can be converted to a number.
5
11
  *
6
- * @return true if the value is number or can convert to a number, otherwise false.
12
+ * @param value - The value to check.
13
+ * @returns `true` if the value is a number or can be converted to a number, otherwise `false`.
7
14
  *
8
15
  * @example
9
16
  * ```ts
10
- * isNumber(123); // true
11
- * isNumber('123'); // true
12
- * isNumber(' 123 '); // true
13
- * isNumber(''); // false
14
- * isNumber(' '); // false
15
- * isNumber(' 123a '); // false
16
- * isNumber(' 123 a '); // false
17
+ * isNumber(123); // true
18
+ * isNumber('123'); // true
19
+ * isNumber(' 123 '); // true
20
+ * isNumber('0xff'); // true
21
+ * isNumber('-1.1'); // true
22
+ * isNumber(''); // false
23
+ * isNumber(' '); // false
24
+ * isNumber(' 123a '); // false
25
+ * isNumber(NaN); // false
26
+ * isNumber(Infinity); // false
27
+ * isNumber({}); // false
28
+ * isNumber([]); // false
29
+ * isNumber(null); // false
30
+ * isNumber(undefined); // false
17
31
  * ```
18
32
  */
19
33
  export declare function isNumber(value: unknown): boolean;
34
+ /**
35
+ * Convert a value to a number if possible.
36
+ *
37
+ * @param value - The value to convert.
38
+ * @returns The converted number if valid, otherwise `null`.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * toNumber(123); // 123
43
+ * toNumber('123'); // 123
44
+ * toNumber(' 123 '); // 123
45
+ * toNumber('0xff'); // 255
46
+ * toNumber('-1.1'); // -1.1
47
+ * toNumber(''); // null
48
+ * toNumber(' '); // null
49
+ * toNumber('123a'); // null
50
+ * toNumber(NaN); // null
51
+ * toNumber(Infinity); // null
52
+ * toNumber({}); // null
53
+ * toNumber([]); // null
54
+ * toNumber(null); // null
55
+ * toNumber(undefined); // null
56
+ * ```
57
+ */
58
+ export declare function toNumber(value: unknown): number | null;
20
59
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQhD"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOtD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBhD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAgBtD"}
package/dist/main.mjs CHANGED
@@ -1,18 +1,41 @@
1
- /* @alwatr/is-number v5.5.0 */
1
+ /* @alwatr/is-number v5.6.1 */
2
2
 
3
3
  // src/main.ts
4
4
  import { packageTracer } from "@alwatr/package-tracer";
5
- __dev_mode__: packageTracer.add("@alwatr/is-number", "5.5.0");
5
+ __dev_mode__: packageTracer.add("@alwatr/is-number", "5.6.1");
6
+ function isFiniteNumber(value) {
7
+ if (typeof Number.isFinite === "function") {
8
+ return Number.isFinite(value);
9
+ }
10
+ return typeof value === "number" && isFinite(value);
11
+ }
6
12
  function isNumber(value) {
7
13
  if (typeof value === "number") {
8
14
  return value - value === 0;
9
15
  }
10
- if (typeof value === "string" && value.trim() !== "") {
11
- return Number.isFinite ? Number.isFinite(+value) : isFinite(+value);
16
+ if (typeof value === "string") {
17
+ const trimmed = value.trim();
18
+ if (trimmed === "") return false;
19
+ const num = +trimmed;
20
+ return isFiniteNumber(num);
12
21
  }
13
22
  return false;
14
23
  }
24
+ function toNumber(value) {
25
+ if (typeof value === "number") {
26
+ return value - value === 0 ? value : null;
27
+ }
28
+ if (typeof value === "string") {
29
+ const trimmed = value.trim();
30
+ if (trimmed === "") return null;
31
+ const num = +trimmed;
32
+ return isFiniteNumber(num) ? num : null;
33
+ }
34
+ return null;
35
+ }
15
36
  export {
16
- isNumber
37
+ isFiniteNumber,
38
+ isNumber,
39
+ toNumber
17
40
  };
18
41
  //# sourceMappingURL=main.mjs.map
package/dist/main.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Check the value is number or can convert to a number, for example string ' 123 ' can be converted to 123\n *\n * @param value - the value must check numeric.\n *\n * @return true if the value is number or can convert to a number, otherwise false.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * isNumber('123'); // true\n * isNumber(' 123 '); // true\n * isNumber(''); // false\n * isNumber(' '); // false\n * isNumber(' 123a '); // false\n * isNumber(' 123 a '); // false\n * ```\n */\nexport function isNumber(value: unknown): boolean {\n if (typeof value === 'number') {\n return value - value === 0;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n return Number.isFinite ? Number.isFinite(+value) : isFinite(+value);\n }\n return false;\n}\n"],
5
- "mappings": ";;;AAAA,SAAQ,qBAAoB;AAE5B,aAAc,eAAc,IAAI,qBAAkB,OAAmB;AAoB9D,SAAS,SAAS,OAAyB;AAChD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU;AAAA,EAC3B;AACA,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,WAAO,OAAO,WAAW,OAAO,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK;AAAA,EACpE;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Polyfill for Number.isFinite - properly checks if a value is a finite number\n * without type coercion.\n *\n * @param value - The value to check\n * @returns true if the value is a finite number, false otherwise\n */\nexport function isFiniteNumber(value: unknown): boolean {\n // Use native implementation if available\n if (typeof Number.isFinite === 'function') {\n return Number.isFinite(value);\n }\n // Fallback implementation\n return typeof value === 'number' && isFinite(value);\n}\n\n/**\n * Check if the value is a number or can be converted to a number.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a number or can be converted to a number, otherwise `false`.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * isNumber('123'); // true\n * isNumber(' 123 '); // true\n * isNumber('0xff'); // true\n * isNumber('-1.1'); // true\n * isNumber(''); // false\n * isNumber(' '); // false\n * isNumber(' 123a '); // false\n * isNumber(NaN); // false\n * isNumber(Infinity); // false\n * isNumber({}); // false\n * isNumber([]); // false\n * isNumber(null); // false\n * isNumber(undefined); // false\n * ```\n */\nexport function isNumber(value: unknown): boolean {\n // Handle number type\n if (typeof value === 'number') {\n return value - value === 0;\n }\n\n // Handle string type\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return false;\n\n // Use unary plus for fastest string-to-number conversion\n const num = +trimmed;\n return isFiniteNumber(num);\n }\n\n return false;\n}\n\n/**\n * Convert a value to a number if possible.\n *\n * @param value - The value to convert.\n * @returns The converted number if valid, otherwise `null`.\n *\n * @example\n * ```ts\n * toNumber(123); // 123\n * toNumber('123'); // 123\n * toNumber(' 123 '); // 123\n * toNumber('0xff'); // 255\n * toNumber('-1.1'); // -1.1\n * toNumber(''); // null\n * toNumber(' '); // null\n * toNumber('123a'); // null\n * toNumber(NaN); // null\n * toNumber(Infinity); // null\n * toNumber({}); // null\n * toNumber([]); // null\n * toNumber(null); // null\n * toNumber(undefined); // null\n * ```\n */\nexport function toNumber(value: unknown): number | null {\n // Handle number type\n if (typeof value === 'number') {\n return value - value === 0 ? value : null;\n }\n\n // Handle string type\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n\n const num = +trimmed;\n return isFiniteNumber(num) ? num : null;\n }\n\n return null;\n}\n"],
5
+ "mappings": ";;;AAAA,SAAQ,qBAAoB;AAE5B,aAAc,eAAc,IAAI,qBAAkB,OAAmB;AAS9D,SAAS,eAAe,OAAyB;AAEtD,MAAI,OAAO,OAAO,aAAa,YAAY;AACzC,WAAO,OAAO,SAAS,KAAK;AAAA,EAC9B;AAEA,SAAO,OAAO,UAAU,YAAY,SAAS,KAAK;AACpD;AA0BO,SAAS,SAAS,OAAyB;AAEhD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU;AAAA,EAC3B;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO;AAG3B,UAAM,MAAM,CAAC;AACb,WAAO,eAAe,GAAG;AAAA,EAC3B;AAEA,SAAO;AACT;AA0BO,SAAS,SAAS,OAA+B;AAEtD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,UAAU,IAAI,QAAQ;AAAA,EACvC;AAGA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO;AAE3B,UAAM,MAAM,CAAC;AACb,WAAO,eAAe,GAAG,IAAI,MAAM;AAAA,EACrC;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/is-number",
3
- "version": "5.5.0",
3
+ "version": "5.6.1",
4
4
  "description": "A simple utility to Check the value is number or can convert to a number, for example string ' 123 ' can be converted to 123.",
5
5
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
6
6
  "keywords": [
@@ -86,14 +86,14 @@
86
86
  "clean": "rm -rfv dist *.tsbuildinfo"
87
87
  },
88
88
  "dependencies": {
89
- "@alwatr/package-tracer": "^5.5.0"
89
+ "@alwatr/package-tracer": "^5.5.2"
90
90
  },
91
91
  "devDependencies": {
92
- "@alwatr/nano-build": "^5.5.0",
92
+ "@alwatr/nano-build": "^5.5.2",
93
93
  "@alwatr/prettier-config": "^5.0.0",
94
94
  "@alwatr/tsconfig-base": "^5.0.0",
95
95
  "jest": "^29.7.0",
96
96
  "typescript": "^5.8.2"
97
97
  },
98
- "gitHead": "fdf8e6de77cca359465110a75ff18faff0649a95"
98
+ "gitHead": "2756475ba2fa108bae7af6d8d9747e0c7815dfa2"
99
99
  }
package/src/main.test.js CHANGED
@@ -1,4 +1,4 @@
1
- import {isNumber} from '@alwatr/is-number';
1
+ import {isNumber, toNumber, isFiniteNumber} from '@alwatr/is-number';
2
2
 
3
3
  describe('isNumber', () => {
4
4
  it('should return true for numbers', () => {
@@ -13,6 +13,9 @@ describe('isNumber', () => {
13
13
  expect(isNumber('0')).toBe(true);
14
14
  expect(isNumber('-123')).toBe(true);
15
15
  expect(isNumber('1.23')).toBe(true);
16
+ expect(isNumber(' 123 ')).toBe(true); // With spaces
17
+ expect(isNumber('0xff')).toBe(true); // Hex
18
+ expect(isNumber('5e3')).toBe(true); // Scientific notation
16
19
  });
17
20
 
18
21
  it('should return false for non-numeric strings', () => {
@@ -43,3 +46,74 @@ describe('isNumber', () => {
43
46
  expect(isNumber(-Infinity)).toBe(false);
44
47
  });
45
48
  });
49
+
50
+ describe('toNumber', () => {
51
+ it('should convert numbers correctly', () => {
52
+ expect(toNumber(123)).toBe(123);
53
+ expect(toNumber(0)).toBe(0);
54
+ expect(toNumber(-123)).toBe(-123);
55
+ expect(toNumber(1.23)).toBe(1.23);
56
+ });
57
+
58
+ it('should convert numeric strings correctly', () => {
59
+ expect(toNumber('123')).toBe(123);
60
+ expect(toNumber('0')).toBe(0);
61
+ expect(toNumber('-123')).toBe(-123);
62
+ expect(toNumber('1.23')).toBe(1.23);
63
+ expect(toNumber(' 123 ')).toBe(123); // With spaces
64
+ expect(toNumber('0xff')).toBe(255); // Hex
65
+ expect(toNumber('5e3')).toBe(5000); // Scientific notation
66
+ });
67
+
68
+ it('should return null for non-numeric strings', () => {
69
+ expect(toNumber('abc')).toBeNull();
70
+ expect(toNumber('123abc')).toBeNull();
71
+ expect(toNumber('')).toBeNull();
72
+ expect(toNumber(' ')).toBeNull();
73
+ });
74
+
75
+ it('should return null for boolean values', () => {
76
+ expect(toNumber(true)).toBeNull();
77
+ expect(toNumber(false)).toBeNull();
78
+ });
79
+
80
+ it('should return null for null and undefined', () => {
81
+ expect(toNumber(null)).toBeNull();
82
+ expect(toNumber(undefined)).toBeNull();
83
+ });
84
+
85
+ it('should return null for objects and arrays', () => {
86
+ expect(toNumber({})).toBeNull();
87
+ expect(toNumber([])).toBeNull();
88
+ });
89
+
90
+ it('should return null for NaN and Infinity', () => {
91
+ expect(toNumber(NaN)).toBeNull();
92
+ expect(toNumber(Infinity)).toBeNull();
93
+ expect(toNumber(-Infinity)).toBeNull();
94
+ });
95
+ });
96
+
97
+ describe('isFiniteNumber', () => {
98
+ it('should return true for finite numbers', () => {
99
+ expect(isFiniteNumber(123)).toBe(true);
100
+ expect(isFiniteNumber(0)).toBe(true);
101
+ expect(isFiniteNumber(-123)).toBe(true);
102
+ expect(isFiniteNumber(1.23)).toBe(true);
103
+ });
104
+
105
+ it('should return false for NaN and Infinity', () => {
106
+ expect(isFiniteNumber(NaN)).toBe(false);
107
+ expect(isFiniteNumber(Infinity)).toBe(false);
108
+ expect(isFiniteNumber(-Infinity)).toBe(false);
109
+ });
110
+
111
+ it('should return false for non-number values without type coercion', () => {
112
+ expect(isFiniteNumber('123')).toBe(false);
113
+ expect(isFiniteNumber(true)).toBe(false);
114
+ expect(isFiniteNumber(null)).toBe(false);
115
+ expect(isFiniteNumber(undefined)).toBe(false);
116
+ expect(isFiniteNumber({})).toBe(false);
117
+ expect(isFiniteNumber([])).toBe(false);
118
+ });
119
+ });