smart-unit 1.0.4 → 2.0.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/README.md +48 -151
- package/README.zh-CN.md +37 -140
- package/dist/SmartUnit.d.ts +60 -0
- package/dist/SmartUnitBase.d.ts +77 -0
- package/dist/SmartUnitPrecision.d.ts +82 -0
- package/dist/index.cjs +166 -0
- package/dist/index.d.ts +3 -104
- package/dist/index.mjs +160 -0
- package/dist/precision.cjs +195 -0
- package/dist/precision.d.ts +9 -0
- package/dist/precision.mjs +189 -0
- package/dist/utils-C1byK7Uk.js +146 -0
- package/dist/utils-DqEXot5a.js +149 -0
- package/dist/utils.d.ts +32 -0
- package/package.json +36 -30
- package/dist/browser.umd.js +0 -14
- package/dist/index.esm.js +0 -228
- package/dist/index.js +0 -235
package/README.md
CHANGED
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
[](https://github.com/flycran/smart-unit/actions)
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
English | <a href="./README.zh-CN.md">中文</a> | <a href="https://flycran.github.io/smart-unit/en">Documentation</a>
|
|
13
|
+
</p>
|
|
12
14
|
|
|
13
15
|
---
|
|
14
16
|
|
|
15
|
-
**smart-unit** is a lightweight
|
|
17
|
+
**smart-unit** is a lightweight automatic unit conversion tool with intelligent formatting.
|
|
16
18
|
|
|
17
19
|
```ts
|
|
18
20
|
import SmartUnit from 'smart-unit';
|
|
@@ -27,14 +29,14 @@ size.parse('2.5GB'); // 2684354560
|
|
|
27
29
|
## Features
|
|
28
30
|
|
|
29
31
|
- 🎯 **Smart Formatting** — Automatically selects the optimal unit for display
|
|
30
|
-
- 🔢 **Bidirectional** —
|
|
31
|
-
- ⚡ **High Performance** — Minimal overhead,
|
|
32
|
-
- 🧮 **High Precision** — Optional `decimal.js` integration for arbitrary precision
|
|
33
|
-
- 📦 **TypeScript First** —
|
|
34
|
-
- 🪶 **Lightweight** — Core functionality with
|
|
35
|
-
- ✅ **Well Tested** —
|
|
32
|
+
- 🔢 **Bidirectional Conversion** — Supports unit formatting (`format`) and reverse parsing (`parse`)
|
|
33
|
+
- ⚡ **High Performance** — Minimal overhead, supports Node.js and browsers
|
|
34
|
+
- 🧮 **High Precision** — Optional `decimal.js` integration for arbitrary precision calculations
|
|
35
|
+
- 📦 **TypeScript First** — Complete type safety
|
|
36
|
+
- 🪶 **Lightweight** — Core functionality with small bundle size
|
|
37
|
+
- ✅ **Well Tested** — 100+ test cases covering various edge cases
|
|
36
38
|
|
|
37
|
-
##
|
|
39
|
+
## Installation
|
|
38
40
|
|
|
39
41
|
```bash
|
|
40
42
|
npm install smart-unit
|
|
@@ -46,7 +48,7 @@ npm install smart-unit
|
|
|
46
48
|
|
|
47
49
|
## Quick Start
|
|
48
50
|
|
|
49
|
-
###
|
|
51
|
+
### Fixed Ratio Units
|
|
50
52
|
|
|
51
53
|
```ts
|
|
52
54
|
import SmartUnit from 'smart-unit';
|
|
@@ -59,7 +61,7 @@ fileSize.format(1024 * 1024 * 100); // => "100MB"
|
|
|
59
61
|
fileSize.format(1536); // => "1.5KB"
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
###
|
|
64
|
+
### Variable Ratio Units
|
|
63
65
|
|
|
64
66
|
```ts
|
|
65
67
|
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km']);
|
|
@@ -68,19 +70,20 @@ length.format(1500); // => "1.5m"
|
|
|
68
70
|
length.format(1500000); // => "1.5km"
|
|
69
71
|
```
|
|
70
72
|
|
|
71
|
-
### High
|
|
73
|
+
### High Precision & BigInt Support
|
|
72
74
|
|
|
73
75
|
```ts
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
import { SmartUnitPrecision } from 'smart-unit/precision'
|
|
77
|
+
|
|
78
|
+
const bigLength = new SmartUnitPrecision(
|
|
79
|
+
['mm', 10, 'cm', 100, 'm', 1000, 'km', 1000, 'Mm', 1000, 'Gm', 1000, 'Tm']
|
|
77
80
|
);
|
|
78
81
|
|
|
79
|
-
//
|
|
82
|
+
// Supports BigInt and values beyond JS safe integer range
|
|
80
83
|
bigLength.format(10n ** 18n); // => "1000Tm"
|
|
81
84
|
```
|
|
82
85
|
|
|
83
|
-
###
|
|
86
|
+
### Parsing Unit Strings
|
|
84
87
|
|
|
85
88
|
```ts
|
|
86
89
|
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h']);
|
|
@@ -89,160 +92,54 @@ time.parse('90s'); // => 90000 (ms)
|
|
|
89
92
|
time.parse('2.5h'); // => 9000000 (ms)
|
|
90
93
|
```
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
### `new SmartUnit(units, options?)`
|
|
95
|
-
|
|
96
|
-
Creates a unit converter instance.
|
|
97
|
-
|
|
98
|
-
#### Parameters
|
|
99
|
-
|
|
100
|
-
- **units** `(string | number)[]` — Array of unit names and conversion ratios
|
|
101
|
-
- Even indices: unit names (e.g., `'B'`, `'KB'`)
|
|
102
|
-
- Odd indices: conversion ratios to next unit (e.g., `1024`)
|
|
103
|
-
- **options** `SmartUnitOptions` — Configuration object
|
|
104
|
-
- `baseDigit?: number` — Auto-generate ratios (e.g., `1024` for all steps)
|
|
105
|
-
- `threshold?: number` — Unit switch threshold (default: `1`)
|
|
106
|
-
- `fractionDigits?: FractionDigits` — Decimal places for formatting
|
|
107
|
-
- `useDecimal?: boolean` — Enable high-precision mode
|
|
108
|
-
- `decimalOptions?: Decimal.Config` — Custom decimal.js configuration
|
|
109
|
-
|
|
110
|
-
#### Methods
|
|
111
|
-
|
|
112
|
-
##### `.format(num, decimal?)`
|
|
113
|
-
|
|
114
|
-
Formats a number to the optimal unit string.
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024, fractionDigits: 2 });
|
|
118
|
-
|
|
119
|
-
size.format(1536); // => "1.50KB"
|
|
120
|
-
size.format(1536, 0); // => "2KB"
|
|
121
|
-
size.format(1536, '1-3'); // => "1.5KB" (min 1, max 3 decimals)
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
##### `.parse(str)`
|
|
125
|
-
|
|
126
|
-
Parses a unit string back to base unit value.
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
130
|
-
|
|
131
|
-
size.parse('1.5KB'); // => 1536
|
|
132
|
-
size.parse('2MB'); // => 2097152
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
##### `.getUnit(num)`
|
|
136
|
-
|
|
137
|
-
Gets the optimal unit and converted value without formatting.
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
141
|
-
|
|
142
|
-
size.getUnit(1536);
|
|
143
|
-
// => { num: 1.5, unit: 'KB' }
|
|
144
|
-
|
|
145
|
-
// With high precision
|
|
146
|
-
const precise = new SmartUnit(['B', 'KB', 1024], { useDecimal: true });
|
|
147
|
-
precise.getUnit(1536);
|
|
148
|
-
// => { num: 1.5, unit: 'KB', decimal: Decimal }
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
##### `.toBase(num, unit)`
|
|
152
|
-
|
|
153
|
-
Converts a value from specified unit to base unit.
|
|
154
|
-
|
|
155
|
-
```ts
|
|
156
|
-
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm']);
|
|
157
|
-
|
|
158
|
-
length.toBase(1.5, 'm'); // => 1500 (mm)
|
|
159
|
-
length.toBase(100, 'cm'); // => 1000 (mm)
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
##### `.splitUnit(str)`
|
|
163
|
-
|
|
164
|
-
Extracts numeric value and unit from a formatted string.
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
168
|
-
|
|
169
|
-
size.splitUnit('1.5KB'); // => { num: 1.5, unit: 'KB' }
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
##### `.fromUnitFormat(num, unit, decimal?)`
|
|
173
|
-
|
|
174
|
-
Converts from one unit to the optimal unit and formats.
|
|
175
|
-
|
|
176
|
-
```ts
|
|
177
|
-
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km']);
|
|
178
|
-
|
|
179
|
-
length.fromUnitFormat(1500, 'm'); // => "1.5km"
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## Use Cases
|
|
183
|
-
|
|
184
|
-
### Data Transfer Rate
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
const bitrate = new SmartUnit(['bps', 'Kbps', 'Mbps', 'Gbps'], {
|
|
188
|
-
baseDigit: 1000,
|
|
189
|
-
fractionDigits: 1,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
bitrate.format(1500000); // => "1.5Mbps"
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Frequency
|
|
95
|
+
### Chain Formatting
|
|
196
96
|
|
|
197
97
|
```ts
|
|
198
|
-
const
|
|
199
|
-
baseDigit: 1000,
|
|
200
|
-
fractionDigits: 2,
|
|
201
|
-
});
|
|
98
|
+
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h']);
|
|
202
99
|
|
|
203
|
-
|
|
100
|
+
time.formatChain(63000) // => 1m3s
|
|
101
|
+
time.formatChain(3663000); // => 1h1m3s
|
|
204
102
|
```
|
|
205
103
|
|
|
206
|
-
###
|
|
104
|
+
### Internationalization
|
|
207
105
|
|
|
208
106
|
```ts
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
```
|
|
107
|
+
const i18nMap = {
|
|
108
|
+
ms: 'ms',
|
|
109
|
+
s: 'seconds',
|
|
110
|
+
m: 'minutes',
|
|
111
|
+
h: 'hours',
|
|
112
|
+
}
|
|
113
|
+
const t = (unit: keyof typeof i18nMap) => i18nMap[unit]
|
|
217
114
|
|
|
218
|
-
|
|
115
|
+
const timeI18n = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h'], {
|
|
116
|
+
separator: ' ',
|
|
117
|
+
}).withConvert(t)
|
|
219
118
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
npm test
|
|
119
|
+
timeI18n.formatChain(90000) // 1minutes 30seconds
|
|
120
|
+
timeI18n.formatChain(9000000) // 2hours 30minutes
|
|
224
121
|
```
|
|
225
122
|
|
|
226
|
-
## TypeScript
|
|
123
|
+
## Using TypeScript
|
|
227
124
|
|
|
228
|
-
|
|
125
|
+
SmartUnit provides complete type safety support for TypeScript projects.
|
|
229
126
|
|
|
230
127
|
```ts
|
|
231
|
-
import SmartUnit from 'smart-unit'
|
|
232
|
-
import type { Decimal } from 'decimal.js';
|
|
128
|
+
import SmartUnit, { type GetUnitNames } from 'smart-unit'
|
|
233
129
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
130
|
+
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h'])
|
|
131
|
+
// Use utility function to export types
|
|
132
|
+
type TimeUnits = GetUnitNames<typeof time> // => type TimeUnits = "m" | "ms" | "s" | "h"
|
|
237
133
|
|
|
238
|
-
//
|
|
239
|
-
const
|
|
240
|
-
|
|
134
|
+
// The t function must accept all TimeUnits units, otherwise a type error will occur
|
|
135
|
+
const timeI18n = time.withConvert(t)
|
|
136
|
+
// The unit parameter of toBase receives TimeUnits type constraint
|
|
137
|
+
time.toBase(60, 'h')
|
|
241
138
|
```
|
|
242
139
|
|
|
243
140
|
## Contributing
|
|
244
141
|
|
|
245
|
-
Contributions are welcome!
|
|
142
|
+
Contributions are welcome! Feel free to submit issues or pull requests.
|
|
246
143
|
|
|
247
144
|
## License
|
|
248
145
|
|
package/README.zh-CN.md
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
[](https://github.com/flycran/smart-unit/actions)
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="./README.md">English</a> | 中文 | <a href="https://flycran.github.io/smart-unit">完整文档</a>
|
|
13
|
+
</p>
|
|
12
14
|
|
|
13
15
|
---
|
|
14
16
|
|
|
@@ -32,7 +34,7 @@ size.parse('2.5GB'); // 2684354560
|
|
|
32
34
|
- 🧮 **高精度** — 可选 `decimal.js` 集成,支持任意精度计算
|
|
33
35
|
- 📦 **TypeScript 优先** — 完整的类型安全
|
|
34
36
|
- 🪶 **轻量级** — 核心功能,体积小巧
|
|
35
|
-
- ✅ **测试完善** —
|
|
37
|
+
- ✅ **测试完善** — 100+ 测试用例,覆盖各种边缘情况
|
|
36
38
|
|
|
37
39
|
## 安装
|
|
38
40
|
|
|
@@ -46,7 +48,7 @@ npm install smart-unit
|
|
|
46
48
|
|
|
47
49
|
## 快速开始
|
|
48
50
|
|
|
49
|
-
###
|
|
51
|
+
### 固定比例单位
|
|
50
52
|
|
|
51
53
|
```ts
|
|
52
54
|
import SmartUnit from 'smart-unit';
|
|
@@ -59,7 +61,7 @@ fileSize.format(1024 * 1024 * 100); // => "100MB"
|
|
|
59
61
|
fileSize.format(1536); // => "1.5KB"
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
###
|
|
64
|
+
### 可变比例单位
|
|
63
65
|
|
|
64
66
|
```ts
|
|
65
67
|
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km']);
|
|
@@ -71,9 +73,10 @@ length.format(1500000); // => "1.5km"
|
|
|
71
73
|
### 高精度与 BigInt 支持
|
|
72
74
|
|
|
73
75
|
```ts
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
import { SmartUnitPrecision } from 'smart-unit/precision'
|
|
77
|
+
|
|
78
|
+
const bigLength = new SmartUnitPrecision(
|
|
79
|
+
['mm', 10, 'cm', 100, 'm', 1000, 'km', 1000, 'Mm', 1000, 'Gm', 1000, 'Tm']
|
|
77
80
|
);
|
|
78
81
|
|
|
79
82
|
// 支持 BigInt 和超出 JS 安全整数范围的数值
|
|
@@ -89,155 +92,49 @@ time.parse('90s'); // => 90000 (ms)
|
|
|
89
92
|
time.parse('2.5h'); // => 9000000 (ms)
|
|
90
93
|
```
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
### `new SmartUnit(units, options?)`
|
|
95
|
-
|
|
96
|
-
创建单位转换器实例。
|
|
97
|
-
|
|
98
|
-
#### 参数
|
|
99
|
-
|
|
100
|
-
- **units** `(string | number)[]` — 单位名称和转换比例数组
|
|
101
|
-
- 偶数索引:单位名称(如 `'B'`、`'KB'`)
|
|
102
|
-
- 奇数索引:到下一单位的转换比例(如 `1024`)
|
|
103
|
-
- **options** `SmartUnitOptions` — 配置对象
|
|
104
|
-
- `baseDigit?: number` — 自动生成比例(如 `1024` 表示所有步骤)
|
|
105
|
-
- `threshold?: number` — 单位切换阈值(默认:`1`)
|
|
106
|
-
- `fractionDigits?: FractionDigits` — 格式化小数位数
|
|
107
|
-
- `useDecimal?: boolean` — 启用高精度模式
|
|
108
|
-
- `decimalOptions?: Decimal.Config` — 自定义 decimal.js 配置
|
|
109
|
-
|
|
110
|
-
#### 方法
|
|
111
|
-
|
|
112
|
-
##### `.format(num, decimal?)`
|
|
113
|
-
|
|
114
|
-
将数字格式化为最优单位字符串。
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024, fractionDigits: 2 });
|
|
118
|
-
|
|
119
|
-
size.format(1536); // => "1.50KB"
|
|
120
|
-
size.format(1536, 0); // => "2KB"
|
|
121
|
-
size.format(1536, '1-3'); // => "1.5KB"(最少1位,最多3位小数)
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
##### `.parse(str)`
|
|
125
|
-
|
|
126
|
-
将单位字符串解析回基本单位值。
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
130
|
-
|
|
131
|
-
size.parse('1.5KB'); // => 1536
|
|
132
|
-
size.parse('2MB'); // => 2097152
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
##### `.getUnit(num)`
|
|
136
|
-
|
|
137
|
-
获取最优单位和转换后的值(不进行格式化)。
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
141
|
-
|
|
142
|
-
size.getUnit(1536);
|
|
143
|
-
// => { num: 1.5, unit: 'KB' }
|
|
144
|
-
|
|
145
|
-
// 高精度模式
|
|
146
|
-
const precise = new SmartUnit(['B', 'KB', 1024], { useDecimal: true });
|
|
147
|
-
precise.getUnit(1536);
|
|
148
|
-
// => { num: 1.5, unit: 'KB', decimal: Decimal }
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
##### `.toBase(num, unit)`
|
|
152
|
-
|
|
153
|
-
将指定单位的值转换为基本单位。
|
|
154
|
-
|
|
155
|
-
```ts
|
|
156
|
-
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm']);
|
|
157
|
-
|
|
158
|
-
length.toBase(1.5, 'm'); // => 1500 (mm)
|
|
159
|
-
length.toBase(100, 'cm'); // => 1000 (mm)
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
##### `.splitUnit(str)`
|
|
163
|
-
|
|
164
|
-
从格式化字符串中提取数值和单位。
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
|
-
const size = new SmartUnit(['B', 'KB', 'MB'], { baseDigit: 1024 });
|
|
168
|
-
|
|
169
|
-
size.splitUnit('1.5KB'); // => { num: 1.5, unit: 'KB' }
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
##### `.fromUnitFormat(num, unit, decimal?)`
|
|
173
|
-
|
|
174
|
-
从一种单位转换到最优单位并格式化。
|
|
175
|
-
|
|
176
|
-
```ts
|
|
177
|
-
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km']);
|
|
178
|
-
|
|
179
|
-
length.fromUnitFormat(1500, 'm'); // => "1.5km"
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## 使用场景
|
|
183
|
-
|
|
184
|
-
### 数据传输速率
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
const bitrate = new SmartUnit(['bps', 'Kbps', 'Mbps', 'Gbps'], {
|
|
188
|
-
baseDigit: 1000,
|
|
189
|
-
fractionDigits: 1,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
bitrate.format(1500000); // => "1.5Mbps"
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### 频率
|
|
95
|
+
### 链式单位
|
|
196
96
|
|
|
197
97
|
```ts
|
|
198
|
-
const
|
|
199
|
-
baseDigit: 1000,
|
|
200
|
-
fractionDigits: 2,
|
|
201
|
-
});
|
|
98
|
+
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h']);
|
|
202
99
|
|
|
203
|
-
|
|
100
|
+
time.formatChain(63000) // => 1m3s
|
|
101
|
+
time.formatChain(3663000); // => 1h1m3s
|
|
204
102
|
```
|
|
205
103
|
|
|
206
|
-
###
|
|
104
|
+
### 国际化
|
|
207
105
|
|
|
208
106
|
```ts
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
```
|
|
107
|
+
const i18nMap = {
|
|
108
|
+
ms: 'ms',
|
|
109
|
+
s: 'seconds',
|
|
110
|
+
m: 'minutes',
|
|
111
|
+
h: 'hours',
|
|
112
|
+
}
|
|
113
|
+
const t = (unit: keyof typeof i18nMap) => i18nMap[unit]
|
|
217
114
|
|
|
218
|
-
|
|
115
|
+
const timeI18n = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h'], {
|
|
116
|
+
separator: ' ',
|
|
117
|
+
}).withConvert(t)
|
|
219
118
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
npm test
|
|
119
|
+
timeI18n.formatChain(90000) // 1minutes 30seconds
|
|
120
|
+
timeI18n.formatChain(9000000) // 2hours 30minutes
|
|
224
121
|
```
|
|
225
122
|
|
|
226
|
-
## TypeScript
|
|
123
|
+
## 使用 TypeScript
|
|
227
124
|
|
|
228
|
-
|
|
125
|
+
SmartUnit拥有完整的类型安全支持,适用于 TypeScript 项目。
|
|
229
126
|
|
|
230
127
|
```ts
|
|
231
|
-
import SmartUnit from 'smart-unit'
|
|
232
|
-
import type { Decimal } from 'decimal.js';
|
|
128
|
+
import SmartUnit, { type GetUnitNames } from 'smart-unit'
|
|
233
129
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
130
|
+
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h'])
|
|
131
|
+
// 使用工具函数导出类型
|
|
132
|
+
type TimeUnits = GetUnitNames<typeof time> // => type TimeUnits = "m" | "ms" | "s" | "h"
|
|
237
133
|
|
|
238
|
-
//
|
|
239
|
-
const
|
|
240
|
-
|
|
134
|
+
// t函数必须能接受所有TimeUnits单位,否则将导致类型错误
|
|
135
|
+
const timeI18n = time.withConvert(t)
|
|
136
|
+
// toBase的unit参数收到TimeUnits类型约束
|
|
137
|
+
time.toBase(60, 'h')
|
|
241
138
|
```
|
|
242
139
|
|
|
243
140
|
## 贡献
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SmartUnitBase } from './SmartUnitBase';
|
|
2
|
+
import { type FormattedValue, type FractionDigits, type InputNumber, type SmartUnitOptions } from './utils';
|
|
3
|
+
export declare class SmartUnit<U extends string = string> extends SmartUnitBase<U> {
|
|
4
|
+
constructor(units: (U | number)[], option?: SmartUnitOptions);
|
|
5
|
+
/**
|
|
6
|
+
* Gets the appropriate unit and adjusted value for the input number
|
|
7
|
+
*
|
|
8
|
+
* @param num - The input number to determine the unit for
|
|
9
|
+
* @param fractionDigits - Decimal precision configuration
|
|
10
|
+
* @returns The FormattedValue object containing the number, unit, and formatted number string
|
|
11
|
+
*/
|
|
12
|
+
getUnit(num: InputNumber, fractionDigits?: FractionDigits): FormattedValue<U>;
|
|
13
|
+
/**
|
|
14
|
+
* Formats a number as a string with unit and optional decimal place configuration
|
|
15
|
+
*
|
|
16
|
+
* @param num - The input number to format
|
|
17
|
+
* @param fractionDigits - Decimal precision configuration (defaults to instance setting)
|
|
18
|
+
* - If a number, defines fixed decimal places
|
|
19
|
+
* - If a string in "min-max" format, defines a range of decimal places
|
|
20
|
+
* - If omitted, uses the instance's default decimal configuration
|
|
21
|
+
* @returns The formatted string with number and unit (e.g. "1.50KB")
|
|
22
|
+
*/
|
|
23
|
+
format(num: InputNumber, fractionDigits?: FractionDigits): string;
|
|
24
|
+
/**
|
|
25
|
+
* Gets the chain of units for the input number
|
|
26
|
+
* @param num - The input number to determine the chain for
|
|
27
|
+
* @returns An array of FormattedValue objects representing the chain of units
|
|
28
|
+
*/
|
|
29
|
+
getChainUnit(num: InputNumber): FormattedValue<U>[];
|
|
30
|
+
/**
|
|
31
|
+
* Formats a number as a chain of units string
|
|
32
|
+
* @param num - The input number to format
|
|
33
|
+
* @returns The formatted chain string
|
|
34
|
+
*/
|
|
35
|
+
formatChain(num: InputNumber, separator?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Converts a value from the specified unit to the base unit
|
|
38
|
+
*
|
|
39
|
+
* @param num - The number to convert
|
|
40
|
+
* @param unit - The original unit of the number
|
|
41
|
+
* @returns The converted value in base unit
|
|
42
|
+
*/
|
|
43
|
+
toBase(num: InputNumber, unit: U): number;
|
|
44
|
+
/**
|
|
45
|
+
* Parses a string with unit into a base unit numeric value
|
|
46
|
+
*
|
|
47
|
+
* @param str - Input string containing a number and unit
|
|
48
|
+
* @returns The value converted to base unit
|
|
49
|
+
*/
|
|
50
|
+
parse(str: string): number;
|
|
51
|
+
/**
|
|
52
|
+
* Converts a value from the original unit to the optimal unit with optional decimal precision
|
|
53
|
+
*
|
|
54
|
+
* @param num - The number to convert
|
|
55
|
+
* @param unit - The original unit
|
|
56
|
+
* @param fractionDigits - Optional decimal places for formatting output
|
|
57
|
+
* @returns The converted number as a formatted string
|
|
58
|
+
*/
|
|
59
|
+
fromUnitFormat(num: InputNumber, unit: U, fractionDigits?: FractionDigits): string;
|
|
60
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type Decimal from 'decimal.js';
|
|
2
|
+
import type { FormattedValue, FractionDigits, InputNumber, SmartUnitOptions } from './utils';
|
|
3
|
+
export declare abstract class SmartUnitBase<U extends string = string, D extends boolean = false> {
|
|
4
|
+
readonly threshold: number;
|
|
5
|
+
readonly separator: string;
|
|
6
|
+
readonly fractionDigits?: FractionDigits;
|
|
7
|
+
readonly unitNames: U[];
|
|
8
|
+
readonly unitDigits: number[];
|
|
9
|
+
_accumulatedDigits?: number[];
|
|
10
|
+
/** Accumulated digits for unit conversion */
|
|
11
|
+
get accumulatedDigits(): number[];
|
|
12
|
+
_sortedUnitNames?: U[];
|
|
13
|
+
/** Sorted unit names by length for efficient lookup */
|
|
14
|
+
get sortedUnitNames(): U[];
|
|
15
|
+
convert?: (str: U) => string;
|
|
16
|
+
constructor(units: (U | number)[], option?: SmartUnitOptions);
|
|
17
|
+
withConvert(convert: (str: U) => string): this;
|
|
18
|
+
protected createAccumulatedDigits(): void;
|
|
19
|
+
protected createSortedUnitNames(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Formats the decimal places of a number
|
|
22
|
+
*
|
|
23
|
+
* @param value - The value to format
|
|
24
|
+
* @param fractionDigits - Decimal precision configuration
|
|
25
|
+
* @returns The formatted string representation of the number
|
|
26
|
+
*/
|
|
27
|
+
formatNumber(value: number | Decimal, fractionDigits?: FractionDigits): string;
|
|
28
|
+
abstract getUnit(num: InputNumber, fractionDigits?: FractionDigits): FormattedValue<U>;
|
|
29
|
+
protected _format(numStr: string, unit: U): string;
|
|
30
|
+
abstract format(num: InputNumber, fractionDigits?: FractionDigits): string;
|
|
31
|
+
/**
|
|
32
|
+
* Gets the chain of units for the input number
|
|
33
|
+
*
|
|
34
|
+
* @param num - The input number to determine the chain for
|
|
35
|
+
* @returns An array of FormattedValue objects representing the chain of units
|
|
36
|
+
*/
|
|
37
|
+
abstract getChainUnit(num: InputNumber): FormattedValue<U>[];
|
|
38
|
+
protected _formatChain(chain: FormattedValue<U>[], separator?: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Formats a number as a chain of units string
|
|
41
|
+
* @param num - The input number to format
|
|
42
|
+
* @returns The formatted chain string
|
|
43
|
+
*/
|
|
44
|
+
formatChain(num: InputNumber, separator?: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Converts a value from the specified unit to the base unit
|
|
47
|
+
*
|
|
48
|
+
* @param num - The number to convert
|
|
49
|
+
* @param unit - The original unit of the number
|
|
50
|
+
* @returns The converted value in base unit
|
|
51
|
+
*/
|
|
52
|
+
abstract toBase(num: InputNumber, unit: U): D extends true ? Decimal : number;
|
|
53
|
+
/**
|
|
54
|
+
* Splits a string into its numeric part and unit
|
|
55
|
+
*
|
|
56
|
+
* @param str - Input string containing a number followed by a unit
|
|
57
|
+
* @returns An object containing the numeric value, unit, and Decimal instance
|
|
58
|
+
* @throws An error if no predefined unit is matched
|
|
59
|
+
*/
|
|
60
|
+
splitUnit(str: string): FormattedValue<U>;
|
|
61
|
+
/**
|
|
62
|
+
* Parses a string with unit into a base unit numeric value
|
|
63
|
+
*
|
|
64
|
+
* @param str - Input string containing a number and unit
|
|
65
|
+
* @returns The value converted to base unit
|
|
66
|
+
*/
|
|
67
|
+
abstract parse(str: string): D extends true ? Decimal : number;
|
|
68
|
+
/**
|
|
69
|
+
* Converts a value from the original unit to the optimal unit with optional decimal precision
|
|
70
|
+
*
|
|
71
|
+
* @param num - The number to convert
|
|
72
|
+
* @param unit - The original unit
|
|
73
|
+
* @param fractionDigits - Optional decimal places for formatting output
|
|
74
|
+
* @returns The converted number as a formatted string
|
|
75
|
+
*/
|
|
76
|
+
abstract fromUnitFormat(num: InputNumber, unit: U, fractionDigits?: FractionDigits): string;
|
|
77
|
+
}
|