@airpower/transformer 2.5.1 → 2.7.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 +127 -345
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,80 +9,41 @@
|
|
|
9
9
|
<a href="https://www.npmjs.com/@airpower/transformer">
|
|
10
10
|
<img src="https://img.shields.io/npm/dm/@airpower/transformer"/>
|
|
11
11
|
</a>
|
|
12
|
-
<a href="https://github.com/AirPowerTeam/AirPower-Transformer/blob/main/LICENSE">
|
|
13
|
-
<img src="https://img.shields.io/npm/l/@airpower/transformer"/>
|
|
14
|
-
</a>
|
|
15
12
|
</p>
|
|
16
13
|
|
|
17
14
|
<p align="center">
|
|
18
|
-
<a href="https://github.com/AirPowerTeam/AirPower-Transformer">Github</a>
|
|
19
|
-
<a href="https://gitee.com/air-power/AirPower-Transformer">Gitee</a>
|
|
15
|
+
<a href="https://github.com/AirPowerTeam/AirPower-Transformer">Github</a> /
|
|
16
|
+
<a href="https://gitee.com/air-power/AirPower-Transformer">Gitee</a> /
|
|
20
17
|
<a href="https://www.npmjs.com/package/@airpower/transformer">NPM</a>
|
|
21
18
|
</p>
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## 📖 项目介绍
|
|
26
|
-
|
|
27
|
-
**AirPower-Transformer** 是一个功能强大且轻量级的 TypeScript 数据转换库,专为简化 **JSON 对象** 与 **类实例**
|
|
28
|
-
之间的双向转换而设计。该库通过装饰器提供了一种声明式的方式来控制数据转换过程,使开发者能够轻松处理复杂的嵌套对象、数组以及具有特定格式要求的数据结构。
|
|
20
|
+
# 🎉 AirPower-Transformer 项目介绍
|
|
29
21
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
| 优势 | 说明 |
|
|
33
|
-
|-----------|----------------------------------|
|
|
34
|
-
| **零依赖** | 不依赖任何外部库,纯 TypeScript 实现,轻量级解决方案 |
|
|
35
|
-
| **类型安全** | 完全基于 TypeScript,提供完整的类型检查和智能提示 |
|
|
36
|
-
| **装饰器驱动** | 使用 TypeScript 装饰器来配置转换行为,代码清晰易懂 |
|
|
37
|
-
| **灵活配置** | 支持前缀、别名、类型转换、自定义转换逻辑等多种配置方式 |
|
|
38
|
-
| **嵌套支持** | 自动处理嵌套对象和数组的转换,支持深层嵌套结构 |
|
|
39
|
-
| **继承友好** | 支持类的继承,装饰器配置可自动继承到子类 |
|
|
40
|
-
|
|
41
|
-
---
|
|
22
|
+
**AirPower-Transformer** 是一个功能强大且易于使用的 TypeScript 数据转换库,专为简化 JSON
|
|
23
|
+
对象与类实例之间的双向转换而设计。该库通过装饰器提供了一种声明式的方式来控制数据转换过程,使开发者能够轻松处理复杂的嵌套对象、数组以及具有特定格式要求的数据结构。
|
|
42
24
|
|
|
43
25
|
## ✨ 主要特性
|
|
44
26
|
|
|
45
|
-
- **双向转换**:支持从 JSON
|
|
27
|
+
- **双向转换**:支持从 JSON 对象到类实例的转换,以及从类实例到 JSON 对象的转换
|
|
46
28
|
- **装饰器驱动**:使用 TypeScript 装饰器来配置转换行为,代码清晰易懂
|
|
47
29
|
- **前缀支持**:可以为整个类或特定字段设置前缀,适应不同 API 的命名规范
|
|
48
30
|
- **字段别名**:支持字段别名映射,解决前后端字段名不一致的问题
|
|
49
|
-
-
|
|
31
|
+
- **类型安全**:完全基于 TypeScript,提供完整的类型检查和智能提示
|
|
50
32
|
- **嵌套对象处理**:自动处理嵌套对象和数组的转换
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
---
|
|
33
|
+
- **自定义转换逻辑**:支持自定义转换函数,满足特殊转换需求
|
|
34
|
+
- **零依赖**:不依赖任何外部库,轻量级解决方案
|
|
55
35
|
|
|
56
36
|
## 💻 安装
|
|
57
37
|
|
|
58
|
-
```
|
|
59
|
-
# npm
|
|
38
|
+
```shell
|
|
60
39
|
npm install @airpower/transformer
|
|
61
|
-
|
|
62
|
-
# yarn
|
|
40
|
+
# or
|
|
63
41
|
yarn add @airpower/transformer
|
|
64
|
-
|
|
65
|
-
# pnpm
|
|
42
|
+
# or
|
|
66
43
|
pnpm add @airpower/transformer
|
|
67
44
|
```
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
- TypeScript >= 4.0
|
|
72
|
-
- 需要在 `tsconfig.json` 中启用以下配置:
|
|
73
|
-
|
|
74
|
-
```json
|
|
75
|
-
{
|
|
76
|
-
"compilerOptions": {
|
|
77
|
-
"experimentalDecorators": true,
|
|
78
|
-
"emitDecoratorMetadata": true
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## 📖 快速开始
|
|
46
|
+
## 📖 使用指南
|
|
86
47
|
|
|
87
48
|
### 基础用法
|
|
88
49
|
|
|
@@ -99,109 +60,15 @@ class User extends Transformer {
|
|
|
99
60
|
const userData = { id: 1, name: 'John', email: 'john@example.com' }
|
|
100
61
|
const user = User.fromJson(userData)
|
|
101
62
|
|
|
102
|
-
console.log(user.id) // 输出: 1
|
|
103
|
-
console.log(user.name) // 输出: 'John'
|
|
104
|
-
|
|
105
63
|
// 将实例转换为 JSON
|
|
106
64
|
const json = user.toJson()
|
|
107
|
-
console.log(json) // 输出: { id: 1, name: 'John', email: 'john@example.com' }
|
|
108
65
|
```
|
|
109
66
|
|
|
110
|
-
###
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
import { Alias, IgnorePrefix, Prefix, Transformer, Type } from '@airpower/transformer'
|
|
114
|
-
|
|
115
|
-
// 定义嵌套类
|
|
116
|
-
@Prefix('addr_')
|
|
117
|
-
class Address extends Transformer {
|
|
118
|
-
id!: number
|
|
119
|
-
|
|
120
|
-
@Alias('street_address')
|
|
121
|
-
street!: string
|
|
122
|
-
|
|
123
|
-
city!: string
|
|
124
|
-
country!: string
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
@Prefix('role_')
|
|
128
|
-
class Role extends Transformer {
|
|
129
|
-
id!: number
|
|
130
|
-
name!: string
|
|
131
|
-
|
|
132
|
-
@IgnorePrefix()
|
|
133
|
-
permissions: string[] = []
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// 主类
|
|
137
|
-
@Prefix('usr_')
|
|
138
|
-
class User extends Transformer {
|
|
139
|
-
id!: number
|
|
140
|
-
|
|
141
|
-
@Alias('full_name')
|
|
142
|
-
name!: string
|
|
143
|
-
|
|
144
|
-
email!: string
|
|
145
|
-
|
|
146
|
-
@IgnorePrefix()
|
|
147
|
-
temporaryToken!: string
|
|
67
|
+
### 装饰器详解
|
|
148
68
|
|
|
149
|
-
|
|
150
|
-
homeAddress!: Address
|
|
69
|
+
#### 1. `@Prefix(prefix: string)`
|
|
151
70
|
|
|
152
|
-
|
|
153
|
-
roles: Role[] = []
|
|
154
|
-
|
|
155
|
-
createdAt!: Date
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// 使用示例
|
|
159
|
-
const jsonData = {
|
|
160
|
-
usr_id: 1,
|
|
161
|
-
full_name: 'John Doe',
|
|
162
|
-
usr_email: 'john@example.com',
|
|
163
|
-
temporaryToken: 'abc123',
|
|
164
|
-
homeAddress: {
|
|
165
|
-
addr_id: 1,
|
|
166
|
-
street_address: '123 Main St',
|
|
167
|
-
addr_city: 'New York',
|
|
168
|
-
addr_country: 'USA'
|
|
169
|
-
},
|
|
170
|
-
roles: [
|
|
171
|
-
{
|
|
172
|
-
role_id: 1,
|
|
173
|
-
role_name: 'Admin',
|
|
174
|
-
permissions: ['read', 'write', 'delete']
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
role_id: 2,
|
|
178
|
-
role_name: 'User',
|
|
179
|
-
permissions: ['read']
|
|
180
|
-
}
|
|
181
|
-
],
|
|
182
|
-
usr_createdAt: '2023-01-01T00:00:00Z'
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// 从 JSON 创建实例
|
|
186
|
-
const user = User.fromJson(jsonData)
|
|
187
|
-
console.log(user.name) // 'John Doe'
|
|
188
|
-
console.log(user.temporaryToken) // 'abc123'
|
|
189
|
-
console.log(user.homeAddress.street) // '123 Main St'
|
|
190
|
-
console.log(user.roles.length) // 2
|
|
191
|
-
console.log(user.roles[0].permissions) // ['read', 'write', 'delete']
|
|
192
|
-
|
|
193
|
-
// 转换回 JSON
|
|
194
|
-
const jsonOutput = user.toJson()
|
|
195
|
-
console.log(JSON.stringify(jsonOutput, null, 2))
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## 🛠️ 装饰器详解
|
|
201
|
-
|
|
202
|
-
### 1. `@Prefix(prefix: string)`
|
|
203
|
-
|
|
204
|
-
为类的所有字段设置统一前缀,适用于 API 返回数据带有统一前缀的场景。
|
|
71
|
+
为类的所有字段设置统一前缀:
|
|
205
72
|
|
|
206
73
|
```typescript
|
|
207
74
|
import { Prefix, Transformer } from '@airpower/transformer'
|
|
@@ -213,19 +80,14 @@ class User extends Transformer {
|
|
|
213
80
|
email!: string // JSON 中对应 'user_email'
|
|
214
81
|
}
|
|
215
82
|
|
|
216
|
-
const user = User.fromJson({
|
|
217
|
-
user_id: 1,
|
|
218
|
-
user_name: 'John',
|
|
219
|
-
user_email: 'john@example.com'
|
|
220
|
-
})
|
|
221
|
-
|
|
83
|
+
const user = User.fromJson({ user_id: 1, user_name: 'John', user_email: 'john@example.com' })
|
|
222
84
|
console.log(user.id) // 输出: 1
|
|
223
85
|
console.log(user.name) // 输出: 'John'
|
|
224
86
|
```
|
|
225
87
|
|
|
226
|
-
|
|
88
|
+
#### 2. `@Alias(alias: string)`
|
|
227
89
|
|
|
228
|
-
|
|
90
|
+
为字段设置别名:
|
|
229
91
|
|
|
230
92
|
```typescript
|
|
231
93
|
import { Alias, Transformer } from '@airpower/transformer'
|
|
@@ -240,19 +102,14 @@ class User extends Transformer {
|
|
|
240
102
|
email!: string // JSON 中对应 'user_email'
|
|
241
103
|
}
|
|
242
104
|
|
|
243
|
-
const user = User.fromJson({
|
|
244
|
-
id: 1,
|
|
245
|
-
full_name: 'John Doe',
|
|
246
|
-
user_email: 'john@example.com'
|
|
247
|
-
})
|
|
248
|
-
|
|
105
|
+
const user = User.fromJson({ id: 1, full_name: 'John Doe', user_email: 'john@example.com' })
|
|
249
106
|
console.log(user.name) // 输出: 'John Doe'
|
|
250
107
|
console.log(user.email) // 输出: 'john@example.com'
|
|
251
108
|
```
|
|
252
109
|
|
|
253
|
-
|
|
110
|
+
#### 3. `@IgnorePrefix()`
|
|
254
111
|
|
|
255
|
-
|
|
112
|
+
让特定字段忽略类级别的前缀:
|
|
256
113
|
|
|
257
114
|
```typescript
|
|
258
115
|
import { IgnorePrefix, Prefix, Transformer } from '@airpower/transformer'
|
|
@@ -265,18 +122,14 @@ class User extends Transformer {
|
|
|
265
122
|
temporaryId!: string // JSON 中对应 'temporaryId',不带前缀
|
|
266
123
|
}
|
|
267
124
|
|
|
268
|
-
const user = User.fromJson({
|
|
269
|
-
api_id: 1,
|
|
270
|
-
temporaryId: 'temp123'
|
|
271
|
-
})
|
|
272
|
-
|
|
125
|
+
const user = User.fromJson({ api_id: 1, temporaryId: 'temp123' })
|
|
273
126
|
console.log(user.id) // 输出: 1
|
|
274
127
|
console.log(user.temporaryId) // 输出: 'temp123'
|
|
275
128
|
```
|
|
276
129
|
|
|
277
|
-
|
|
130
|
+
#### 4. `@Type(constructor: Class, isArray: boolean)`
|
|
278
131
|
|
|
279
|
-
|
|
132
|
+
指定字段的类型,支持嵌套对象和数组:
|
|
280
133
|
|
|
281
134
|
```typescript
|
|
282
135
|
import { Transformer, Type } from '@airpower/transformer'
|
|
@@ -301,11 +154,7 @@ class User extends Transformer {
|
|
|
301
154
|
const userData = {
|
|
302
155
|
id: 1,
|
|
303
156
|
name: 'John',
|
|
304
|
-
address: {
|
|
305
|
-
street: '123 Main St',
|
|
306
|
-
city: 'New York',
|
|
307
|
-
zipCode: '10001'
|
|
308
|
-
},
|
|
157
|
+
address: { street: '123 Main St', city: 'New York', zipCode: '10001' },
|
|
309
158
|
addresses: [
|
|
310
159
|
{ street: '456 Oak Ave', city: 'Boston', zipCode: '02101' },
|
|
311
160
|
{ street: '789 Pine Rd', city: 'Chicago', zipCode: '60601' }
|
|
@@ -318,12 +167,12 @@ console.log(user.addresses.length) // 输出: 2
|
|
|
318
167
|
console.log(user.addresses[0].city) // 输出: 'Boston'
|
|
319
168
|
```
|
|
320
169
|
|
|
321
|
-
|
|
170
|
+
#### 5. `@ToClass(func: (json) => any)` 和 `@ToJson(func: (instance) => any)`
|
|
322
171
|
|
|
323
|
-
|
|
172
|
+
自定义转换逻辑:
|
|
324
173
|
|
|
325
174
|
```typescript
|
|
326
|
-
import { ToClass, Transformer } from '@airpower/transformer'
|
|
175
|
+
import { ToClass, ToJson, Transformer } from '@airpower/transformer'
|
|
327
176
|
|
|
328
177
|
class User extends Transformer {
|
|
329
178
|
id!: number
|
|
@@ -331,72 +180,105 @@ class User extends Transformer {
|
|
|
331
180
|
|
|
332
181
|
@ToClass(json => new Date(json.birthday_timestamp * 1000))
|
|
333
182
|
birthday!: Date
|
|
183
|
+
|
|
184
|
+
@ToJson(instance => Math.floor(instance.birthday.getTime() / 1000))
|
|
185
|
+
birthdayTimestamp!: number
|
|
334
186
|
}
|
|
335
187
|
|
|
336
188
|
const userData = {
|
|
337
189
|
id: 1,
|
|
338
190
|
name: 'John',
|
|
339
|
-
birthday_timestamp: 1609459200 // 2021-01-01
|
|
191
|
+
birthday_timestamp: 1609459200 // 2021-01-01
|
|
340
192
|
}
|
|
341
193
|
|
|
342
194
|
const user = User.fromJson(userData)
|
|
343
195
|
console.log(user.birthday) // 输出: Date 对象 (2021-01-01)
|
|
344
196
|
```
|
|
345
197
|
|
|
346
|
-
###
|
|
347
|
-
|
|
348
|
-
自定义从类实例到 JSON 的转换逻辑,适用于需要特殊格式输出的字段。
|
|
198
|
+
### 完整示例
|
|
349
199
|
|
|
350
200
|
```typescript
|
|
351
|
-
import {
|
|
201
|
+
import { Alias, IgnorePrefix, Prefix, Transformer, Type } from '@airpower/transformer'
|
|
352
202
|
|
|
353
|
-
|
|
203
|
+
// 定义嵌套类
|
|
204
|
+
@Prefix('addr_')
|
|
205
|
+
class Address extends Transformer {
|
|
354
206
|
id!: number
|
|
355
|
-
|
|
356
|
-
|
|
207
|
+
@Alias('street_address')
|
|
208
|
+
street!: string
|
|
357
209
|
|
|
358
|
-
|
|
359
|
-
|
|
210
|
+
city!: string
|
|
211
|
+
country!: string
|
|
360
212
|
}
|
|
361
213
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
214
|
+
@Prefix('role_')
|
|
215
|
+
class Role extends Transformer {
|
|
216
|
+
id!: number
|
|
217
|
+
name!: string
|
|
218
|
+
@IgnorePrefix()
|
|
219
|
+
permissions: string[] = []
|
|
220
|
+
}
|
|
366
221
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
222
|
+
// 主类
|
|
223
|
+
@Prefix('usr_')
|
|
224
|
+
class User extends Transformer {
|
|
225
|
+
id!: number
|
|
226
|
+
@Alias('full_name')
|
|
227
|
+
name!: string
|
|
370
228
|
|
|
371
|
-
|
|
229
|
+
email!: string
|
|
372
230
|
|
|
373
|
-
|
|
231
|
+
@IgnorePrefix()
|
|
232
|
+
temporaryToken!: string
|
|
374
233
|
|
|
375
|
-
|
|
234
|
+
@Type(Address)
|
|
235
|
+
homeAddress!: Address
|
|
376
236
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
| `fromJson(json)` | `json: IJson` | `T` | 从 JSON 对象创建类实例,自动进行数据别名转换 |
|
|
380
|
-
| `fromJsonArray(jsonArray)` | `jsonArray: IJson \| IJson[]` | `T[]` | 从 JSON 数组创建类实例数组 |
|
|
381
|
-
| `newInstance(Class, json?)` | `Class: Constructor`, `json?: IJson` | `T` | 创建类的新实例,可选择性地用 JSON 数据初始化 |
|
|
382
|
-
| `copy()` | - | `this` | 复制当前实例到新实例 |
|
|
383
|
-
| `expose(...fields)` | `fields: string[]` | `void` | 只保留指定的字段,其他字段设为 `undefined` |
|
|
384
|
-
| `exclude(...fields)` | `fields: string[]` | `void` | 排除指定的字段,将指定字段设为 `undefined` |
|
|
385
|
-
| `recoverBy(json)` | `json: IJson \| Transformer` | `void` | 用指定的 JSON 数据恢复/覆盖当前实例状态 |
|
|
386
|
-
| `toJson()` | - | `IJson` | 将实例转换为 JSON 对象,自动进行数据别名转换 |
|
|
237
|
+
@Type(Role, true)
|
|
238
|
+
roles: Role[] = []
|
|
387
239
|
|
|
388
|
-
|
|
240
|
+
createdAt!: Date
|
|
241
|
+
}
|
|
389
242
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
243
|
+
// 使用示例
|
|
244
|
+
const jsonData = {
|
|
245
|
+
usr_id: 1,
|
|
246
|
+
full_name: 'John Doe',
|
|
247
|
+
usr_email: 'john@example.com',
|
|
248
|
+
temporaryToken: 'abc123',
|
|
249
|
+
homeAddress: {
|
|
250
|
+
addr_id: 1,
|
|
251
|
+
street_address: '123 Main St',
|
|
252
|
+
addr_city: 'New York',
|
|
253
|
+
addr_country: 'USA'
|
|
254
|
+
},
|
|
255
|
+
roles: [
|
|
256
|
+
{
|
|
257
|
+
role_id: 1,
|
|
258
|
+
role_name: 'Admin',
|
|
259
|
+
permissions: ['read', 'write', 'delete']
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
role_id: 2,
|
|
263
|
+
role_name: 'User',
|
|
264
|
+
permissions: ['read']
|
|
265
|
+
}
|
|
266
|
+
],
|
|
267
|
+
usr_createdAt: '2023-01-01T00:00:00Z'
|
|
268
|
+
}
|
|
398
269
|
|
|
399
|
-
|
|
270
|
+
// 从 JSON 创建实例
|
|
271
|
+
const user = User.fromJson(jsonData)
|
|
272
|
+
console.log(user.name) // 'John Doe'
|
|
273
|
+
console.log(user.temporaryToken) // 'abc123'
|
|
274
|
+
console.log(user.homeAddress.street) // '123 Main St'
|
|
275
|
+
console.log(user.roles.length) // 2
|
|
276
|
+
console.log(user.roles[0].permissions) // ['read', 'write', 'delete']
|
|
277
|
+
|
|
278
|
+
// 转换回 JSON
|
|
279
|
+
const jsonOutput = user.toJson()
|
|
280
|
+
console.log(JSON.stringify(jsonOutput, null, 2))
|
|
281
|
+
```
|
|
400
282
|
|
|
401
283
|
## 🚀 常见使用场景
|
|
402
284
|
|
|
@@ -404,144 +286,53 @@ console.log(json.birthdayTimestamp) // 输出: 1609459200
|
|
|
404
286
|
|
|
405
287
|
当后端 API 返回的数据格式与前端模型不匹配时,使用装饰器可以轻松完成数据转换。
|
|
406
288
|
|
|
407
|
-
```typescript
|
|
408
|
-
@Prefix('data_')
|
|
409
|
-
class ApiResponse extends Transformer {
|
|
410
|
-
@Type(User)
|
|
411
|
-
userInfo!: User
|
|
412
|
-
|
|
413
|
-
@Alias('status_code')
|
|
414
|
-
statusCode!: number
|
|
415
|
-
}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
289
|
### 2. 数据验证和清洗
|
|
419
290
|
|
|
420
291
|
在数据进入应用之前,通过转换过程进行初步的验证和清洗。
|
|
421
292
|
|
|
422
|
-
```typescript
|
|
423
|
-
class User extends Transformer {
|
|
424
|
-
@ToClass(json => json.email?.toLowerCase().trim())
|
|
425
|
-
email!: string
|
|
426
|
-
|
|
427
|
-
@ToClass(json => json.phone?.replace(/\D/g, ''))
|
|
428
|
-
phone!: string
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
293
|
### 3. 不同系统间的数据交换
|
|
433
294
|
|
|
434
295
|
在微服务架构中,不同服务可能使用不同的数据格式,此库可以帮助统一数据格式。
|
|
435
296
|
|
|
436
|
-
```typescript
|
|
437
|
-
@Prefix('legacy_')
|
|
438
|
-
class LegacySystemData extends Transformer {
|
|
439
|
-
@Alias('USER_ID')
|
|
440
|
-
userId!: number
|
|
441
|
-
|
|
442
|
-
@Alias('USER_NAME')
|
|
443
|
-
userName!: string
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
297
|
### 4. 前后端数据格式差异
|
|
448
298
|
|
|
449
299
|
解决前端和后端开发团队使用不同命名约定的问题。
|
|
450
300
|
|
|
451
|
-
|
|
452
|
-
// 后端使用 snake_case,前端使用 camelCase
|
|
453
|
-
@Prefix('user_')
|
|
454
|
-
class User extends Transformer {
|
|
455
|
-
@Alias('created_at')
|
|
456
|
-
createdAt!: Date
|
|
301
|
+
## 🛠️ API 参考
|
|
457
302
|
|
|
458
|
-
|
|
459
|
-
updatedAt!: Date
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### 5. 日期时间处理
|
|
464
|
-
|
|
465
|
-
处理不同系统间的日期时间格式转换。
|
|
466
|
-
|
|
467
|
-
```typescript
|
|
468
|
-
class Event extends Transformer {
|
|
469
|
-
@ToClass(json => new Date(json.event_date))
|
|
470
|
-
eventDate!: Date
|
|
471
|
-
|
|
472
|
-
@ToJson(instance => instance.eventDate.toISOString())
|
|
473
|
-
eventDateIso!: string
|
|
474
|
-
}
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
---
|
|
478
|
-
|
|
479
|
-
## 🔧 开发指南
|
|
480
|
-
|
|
481
|
-
### 项目结构
|
|
482
|
-
|
|
483
|
-
```
|
|
484
|
-
src/
|
|
485
|
-
├── decorator/ # 装饰器实现
|
|
486
|
-
│ ├── Alias.ts # 字段别名装饰器
|
|
487
|
-
│ ├── IgnorePrefix.ts # 忽略前缀装饰器
|
|
488
|
-
│ ├── Prefix.ts # 类前缀装饰器
|
|
489
|
-
│ ├── ToClass.ts # 自定义类转换装饰器
|
|
490
|
-
│ ├── ToJson.ts # 自定义 JSON 转换装饰器
|
|
491
|
-
│ └── Type.ts # 类型转换装饰器
|
|
492
|
-
├── transformer/ # 核心转换器实现
|
|
493
|
-
│ ├── IJson.ts # JSON 接口定义
|
|
494
|
-
│ ├── ITransformerConstructor.ts # 构造函数接口
|
|
495
|
-
│ └── Transformer.ts # 主转换器类
|
|
496
|
-
├── type/ # 类型定义
|
|
497
|
-
│ └── index.ts # 类型导出
|
|
498
|
-
├── util/ # 工具类
|
|
499
|
-
│ └── DecoratorUtil.ts # 装饰器工具类
|
|
500
|
-
└── index.ts # 主入口文件
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### 构建命令
|
|
504
|
-
|
|
505
|
-
```bash
|
|
506
|
-
# 安装依赖
|
|
507
|
-
npm install
|
|
508
|
-
|
|
509
|
-
# 运行 ESLint 检查、TypeScript 编译和 Vite 打包
|
|
510
|
-
npm run build
|
|
511
|
-
```
|
|
303
|
+
### Transformer 类方法
|
|
512
304
|
|
|
513
|
-
|
|
305
|
+
| 方法 | 描述 |
|
|
306
|
+
|-----------------------------|---------------------------|
|
|
307
|
+
| `fromJson(json)` | 从 JSON 对象创建类实例 |
|
|
308
|
+
| `fromJsonArray(jsonArray)` | 从 JSON 数组创建类实例数组 |
|
|
309
|
+
| `newInstance(Class, json?)` | 创建类的新实例,可选择性地用 JSON 数据初始化 |
|
|
310
|
+
| `copy()` | 复制当前实例 |
|
|
311
|
+
| `expose(...fields)` | 只保留指定的字段 |
|
|
312
|
+
| `exclude(...fields)` | 排除指定的字段 |
|
|
313
|
+
| `recoverBy(json)` | 用 JSON 数据恢复实例状态 |
|
|
314
|
+
| `toJson()` | 将实例转换为 JSON |
|
|
514
315
|
|
|
515
|
-
|
|
516
|
-
- 更新 `package.json` 中的版本号
|
|
517
|
-
- 使用 `yarn build` 构建项目
|
|
518
|
-
- 使用 `npm publish` 发布包
|
|
519
|
-
- 使用 `git add/commit/push` 将本地所有变更的文件推送到 Github
|
|
520
|
-
- 根据当前版本创建 `git tag` 并推送到Github,格式例如 `v1.2.3`
|
|
316
|
+
### 装饰器
|
|
521
317
|
|
|
522
|
-
|
|
318
|
+
| 装饰器 | 参数 | 描述 |
|
|
319
|
+
|-----------------------------------------------|-------------|-------------------|
|
|
320
|
+
| `@Prefix(prefix: string)` | 前缀字符串 | 为类的所有字段设置统一前缀 |
|
|
321
|
+
| `@Alias(alias: string)` | 别名字符串 | 为字段设置别名 |
|
|
322
|
+
| `@IgnorePrefix()` | 无 | 让字段忽略类级别的前缀 |
|
|
323
|
+
| `@Type(constructor: Class, isArray: boolean)` | 类构造函数和是否为数组 | 指定字段的类型 |
|
|
324
|
+
| `@ToClass(func: (json) => any)` | 自定义转换函数 | 自定义从 JSON 到类的转换逻辑 |
|
|
325
|
+
| `@ToJson(func: (instance) => any)` | 自定义转换函数 | 自定义从类到 JSON 的转换逻辑 |
|
|
523
326
|
|
|
524
327
|
## 🤝 贡献
|
|
525
328
|
|
|
526
329
|
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目!
|
|
527
330
|
|
|
528
|
-
### 贡献步骤
|
|
529
|
-
|
|
530
|
-
1. Fork 本仓库
|
|
531
|
-
2. 创建你的特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
532
|
-
3. 提交你的更改 (`git commit -m 'Add some AmazingFeature'`)
|
|
533
|
-
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
534
|
-
5. 开启一个 Pull Request
|
|
535
|
-
|
|
536
|
-
---
|
|
537
|
-
|
|
538
331
|
## ⏰ 支持与反馈
|
|
539
332
|
|
|
540
|
-
|
|
541
|
-
- 💡 **需求建议**:欢迎通过本仓库的 [Issues](https://github.com/AirPowerTeam/AirPower-Transformer/issues) 提出
|
|
542
|
-
- 💬 **技术交流**:加入 QQ 群 **555156313** 与我们及时反馈
|
|
333
|
+
如有疑问,可以通过本仓库的 **Issues** 与我们联系,如果你有一些代码贡献,可以通过 **Pull Request** 将代码贡献,为这个项目添砖加瓦。
|
|
543
334
|
|
|
544
|
-
|
|
335
|
+
如果有更多的需求和建议,欢迎通过本仓库的 `Issues` 提出,也欢迎加入 QQ群 555156313 与我们及时反馈。
|
|
545
336
|
|
|
546
337
|
## 📄 许可证
|
|
547
338
|
|
|
@@ -549,17 +340,8 @@ MIT License
|
|
|
549
340
|
|
|
550
341
|
---
|
|
551
342
|
|
|
552
|
-
## 👥 团队信息
|
|
553
|
-
|
|
554
|
-
- **作者**:Hamm
|
|
555
|
-
- **邮箱**:admin@hamm.cn
|
|
556
|
-
- **Github**:[HammCn](https://github.com/HammCn)
|
|
557
|
-
- **团队**:[AirPowerTeam](https://github.com/AirPowerTeam)
|
|
558
|
-
|
|
559
|
-
---
|
|
560
|
-
|
|
561
343
|
<p align="center">
|
|
562
|
-
<a href="https://github.com/AirPowerTeam/AirPower-Transformer">Github</a>
|
|
563
|
-
<a href="https://gitee.com/air-power/AirPower-Transformer">Gitee</a>
|
|
344
|
+
<a href="https://github.com/AirPowerTeam/AirPower-Transformer">Github</a> /
|
|
345
|
+
<a href="https://gitee.com/air-power/AirPower-Transformer">Gitee</a> /
|
|
564
346
|
<a href="https://www.npmjs.com/package/@airpower/transformer">NPM</a>
|
|
565
347
|
</p>
|