@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 +29 -8
- package/README.md +82 -16
- package/dist/main.cjs +31 -6
- package/dist/main.cjs.map +2 -2
- package/dist/main.d.ts +49 -10
- package/dist/main.d.ts.map +1 -1
- package/dist/main.mjs +28 -5
- package/dist/main.mjs.map +2 -2
- package/package.json +5 -5
- package/src/main.test.js +75 -1
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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
|
|
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
|
-
|
|
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');
|
|
23
|
-
console.log(+[]);
|
|
24
|
-
console.log(+'');
|
|
25
|
-
console.log(+' ');
|
|
26
|
-
console.log(typeof NaN);
|
|
27
|
-
console.log(typeof Infinity);
|
|
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
|
-
###
|
|
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(
|
|
48
|
-
isNumber(parseFloat('012')); // true
|
|
80
|
+
isNumber(' 123 '); // true
|
|
49
81
|
```
|
|
50
82
|
|
|
51
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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"
|
|
34
|
-
|
|
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
|
-
|
|
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 *
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4B;AAE5B,aAAc,qCAAc,IAAI,qBAAkB,OAAmB;
|
|
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
|
-
*
|
|
2
|
+
* Polyfill for Number.isFinite - properly checks if a value is a finite number
|
|
3
|
+
* without type coercion.
|
|
3
4
|
*
|
|
4
|
-
* @param value -
|
|
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
|
-
* @
|
|
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);
|
|
11
|
-
* isNumber('123');
|
|
12
|
-
* isNumber(' 123 ');
|
|
13
|
-
* isNumber('');
|
|
14
|
-
* isNumber('
|
|
15
|
-
* isNumber('
|
|
16
|
-
* isNumber('
|
|
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
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAIA
|
|
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.
|
|
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.
|
|
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"
|
|
11
|
-
|
|
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
|
-
|
|
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 *
|
|
5
|
-
"mappings": ";;;AAAA,SAAQ,qBAAoB;AAE5B,aAAc,eAAc,IAAI,qBAAkB,OAAmB;
|
|
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.
|
|
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.
|
|
89
|
+
"@alwatr/package-tracer": "^5.5.1"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@alwatr/nano-build": "^5.
|
|
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.
|
|
96
|
+
"typescript": "^5.8.2"
|
|
97
97
|
},
|
|
98
|
-
"gitHead": "
|
|
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
|
+
});
|