@alwatr/is-number 5.4.0 → 5.6.0

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,27 @@
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.0](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@5.5.0...@alwatr/is-number@5.6.0) (2025-03-18)
7
+
8
+ ### Features
9
+
10
+ * **is-number:** add polyfill for Number.isFinite to check finite numbers ([27c60b1](https://github.com/Alwatr/nanolib/commit/27c60b16e69e87fd62dee25ee21012651b9ba7ca)) by @alimd
11
+ * **is-number:** add toNumber function to convert various values to numbers ([3f4a9d1](https://github.com/Alwatr/nanolib/commit/3f4a9d1d316ba685c47cafdee031e231ef0d40c5)) by @alimd
12
+
13
+ ### Code Refactoring
14
+
15
+ * **is-number:** enhance isNumber function to handle additional cases and improve documentation ([16f16b4](https://github.com/Alwatr/nanolib/commit/16f16b41c487f874f94dd64aaa778c618879db82)) by @alimd
16
+
17
+ ## [5.5.0](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@5.4.0...@alwatr/is-number@5.5.0) (2025-03-06)
18
+
19
+ ### Miscellaneous Chores
20
+
21
+ * update username casing in changelog entries ([9722ac9](https://github.com/Alwatr/nanolib/commit/9722ac9a078438a4e8ebfa5826ea70e0e3a52ca6)) by @
22
+
23
+ ### Dependencies update
24
+
25
+ * bump the development-dependencies group across 1 directory with 11 updates ([720c395](https://github.com/Alwatr/nanolib/commit/720c3954da55c929fe8fb16957121f4c51fb7f0c)) by @dependabot[bot]
26
+
6
27
  ## [5.4.0](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.1.8...@alwatr/is-number@5.4.0) (2025-02-18)
7
28
 
8
29
  ## 5.3.0 (2025-02-03)
@@ -107,7 +128,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
107
128
 
108
129
  ### Miscellaneous Chores
109
130
 
110
- - include LICENSE and LEGAL files to publish ([09f366f](https://github.com/Alwatr/nanolib/commit/09f366f680bfa9fb26acb2cd1ccbc68c5a9e9ad8)) by @AliMD
131
+ - include LICENSE and LEGAL files to publish ([09f366f](https://github.com/Alwatr/nanolib/commit/09f366f680bfa9fb26acb2cd1ccbc68c5a9e9ad8)) by @alimd
111
132
 
112
133
  ## [1.1.3](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.1.2...@alwatr/is-number@1.1.3) (2024-10-11)
113
134
 
@@ -136,7 +157,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
136
157
  ### Miscellaneous Chores
137
158
 
138
159
  - **is-number:** change the license to AGPL-3.0 ([3ad68cb](https://github.com/Alwatr/nanolib/commit/3ad68cb43659fe2af8358ff1393e0085e85b8857)) by @ArmanAsadian
139
- - Update build and lint scripts ([392d0b7](https://github.com/Alwatr/nanolib/commit/392d0b71f446bce336b0256119a80f07aff794ba)) by @AliMD
160
+ - Update build and lint scripts ([392d0b7](https://github.com/Alwatr/nanolib/commit/392d0b71f446bce336b0256119a80f07aff794ba)) by @alimd
140
161
 
141
162
  ### Dependencies update
142
163
 
@@ -151,7 +172,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
151
172
  ### Dependencies update
152
173
 
153
174
  - bump the development-dependencies group across 1 directory with 10 updates ([9ed98ff](https://github.com/Alwatr/nanolib/commit/9ed98ffd0668d5a36e255c82edab3af53bffda8f)) by @dependabot[bot]
154
- - update ([c36ed50](https://github.com/Alwatr/nanolib/commit/c36ed50f68da2f5608ccd96119963a16cfacb4ce)) by @AliMD
175
+ - update ([c36ed50](https://github.com/Alwatr/nanolib/commit/c36ed50f68da2f5608ccd96119963a16cfacb4ce)) by @alimd
155
176
 
156
177
  ## [1.0.9](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.0.8...@alwatr/is-number@1.0.9) (2024-08-31)
157
178
 
@@ -163,7 +184,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
163
184
 
164
185
  ### Dependencies update
165
186
 
166
- - update all dependencies ([1e0c30e](https://github.com/Alwatr/nanolib/commit/1e0c30e6a3a8e19deb5185814e24ab6c08dca573)) by @AliMD
187
+ - update all dependencies ([1e0c30e](https://github.com/Alwatr/nanolib/commit/1e0c30e6a3a8e19deb5185814e24ab6c08dca573)) by @alimd
167
188
 
168
189
  ## [1.0.7](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.0.6...@alwatr/is-number@1.0.7) (2024-07-04)
169
190
 
@@ -175,7 +196,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
175
196
 
176
197
  ### Dependencies update
177
198
 
178
- - upgrade ([6dbd300](https://github.com/Alwatr/nanolib/commit/6dbd300642c9bcc9e7d0b281e244bf1b06eb1c38)) by @AliMD
199
+ - upgrade ([6dbd300](https://github.com/Alwatr/nanolib/commit/6dbd300642c9bcc9e7d0b281e244bf1b06eb1c38)) by @alimd
179
200
 
180
201
  ## [1.0.5](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.0.4...@alwatr/is-number@1.0.5) (2024-04-25)
181
202
 
@@ -189,7 +210,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
189
210
 
190
211
  ### Miscellaneous Chores
191
212
 
192
- - **deps:** update ([1a45030](https://github.com/Alwatr/nanolib/commit/1a450305440b710a300787d4ca24b1ed8c6a39d7)) by @AliMD
213
+ - **deps:** update ([1a45030](https://github.com/Alwatr/nanolib/commit/1a450305440b710a300787d4ca24b1ed8c6a39d7)) by @alimd
193
214
 
194
215
  ## [1.0.2](https://github.com/Alwatr/nanolib/compare/@alwatr/is-number@1.0.1...@alwatr/is-number@1.0.2) (2024-01-24)
195
216
 
@@ -203,9 +224,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
203
224
 
204
225
  ### Bug Fixes
205
226
 
206
- - **is-number:** Remove Number.isFinite polyfill ([aa149f3](https://github.com/Alwatr/nanolib/commit/aa149f302f96d961b058fc3a9d70399c1023cbe3)) by @AliMD
227
+ - **is-number:** Remove Number.isFinite polyfill ([aa149f3](https://github.com/Alwatr/nanolib/commit/aa149f302f96d961b058fc3a9d70399c1023cbe3)) by @alimd
207
228
 
208
229
  ### Features
209
230
 
210
231
  - **is-number:** extract from @alwatr/util ([1c8a676](https://github.com/Alwatr/nanolib/commit/1c8a676ccefcad12436f41b96eeb39c60cc09040)) by @njfamirm
211
- - **is-number:** Update is-number package description and add Number.isFinite polyfill ([a7c8e38](https://github.com/Alwatr/nanolib/commit/a7c8e38eb3e939199cf5637feaf08ac0ed98e2e6)) by @AliMD
232
+ - **is-number:** Update is-number package description and add Number.isFinite polyfill ([a7c8e38](https://github.com/Alwatr/nanolib/commit/a7c8e38eb3e939199cf5637feaf08ac0ed98e2e6)) by @alimd
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.4.0 */
1
+ /* @alwatr/is-number v5.6.0 */
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.4.0");
30
+ __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/is-number", "5.6.0");
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.4.0 */
1
+ /* @alwatr/is-number v5.6.0 */
2
2
 
3
3
  // src/main.ts
4
4
  import { packageTracer } from "@alwatr/package-tracer";
5
- __dev_mode__: packageTracer.add("@alwatr/is-number", "5.4.0");
5
+ __dev_mode__: packageTracer.add("@alwatr/is-number", "5.6.0");
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.4.0",
3
+ "version": "5.6.0",
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.4.0"
89
+ "@alwatr/package-tracer": "^5.5.1"
90
90
  },
91
91
  "devDependencies": {
92
- "@alwatr/nano-build": "^5.4.0",
92
+ "@alwatr/nano-build": "^5.5.1",
93
93
  "@alwatr/prettier-config": "^5.0.0",
94
94
  "@alwatr/tsconfig-base": "^5.0.0",
95
95
  "jest": "^29.7.0",
96
- "typescript": "^5.7.3"
96
+ "typescript": "^5.8.2"
97
97
  },
98
- "gitHead": "074be0d0fe780bf929e163045f8f598cd2697636"
98
+ "gitHead": "21cb1fe0f26a580944d9e72a313fc99308cd8be7"
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
+ });