🌙 why class-transformer (opens new window)
假设我们有一个user.json
文件,里面有user
数组:
[
{
"id": 1,
"firstName": "Johny",
"lastName": "Cage",
"age": 27
},
{
"id": 2,
"firstName": "Ismoil",
"lastName": "Somoni",
"age": 50
},
{
"id": 3,
"firstName": "Luke",
"lastName": "Dacascos",
"age": 12
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
我们还有一个 User class
类:
export class User {
id: number;
firstName: string;
lastName: string;
age: number;
constructor(id: number, firstName: string, lastName: string, age: number) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
getName() {
return this.firstName + ' ' + this.lastName;
}
isAdult() {
return this.age > 36 && this.age < 60;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
然后我们想将这个数组转换为User class
数组,如果直接读取json文件,那么就没法使用User类的实例方法,如:isAdult
,那么我们就需要使用
class-transformer
这个库来转换。
import {plainToInstance} from 'class-transformer';
import path from 'node:path';
import {readFileSync} from 'node:fs';
import {fileURLToPath} from 'node:url';
import usersJson from "./data/user.json" with {type: 'json'};
// 获取 ESM 模式下的正确路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 读取 JSON 文件
const rawData = readFileSync(
path.join(__dirname, 'data/user.json'), // 注意相对路径层级
'utf-8'
);
// const usersJson = JSON.parse(rawData);
// 将user.json数组转换为User数组
// before:
try {
const users: User[] = JSON.parse(rawData);
console.log(users[0]?.isAdult())
} catch (e) {
// TypeError: users[0]?.isAdult is not a function
console.log(e);
}
// now:
const realUsers = plainToInstance(User, usersJson);
console.log(realUsers[0].isAdult()); // false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
🌙 how
- 安装依赖
npm install reflect-metadata --save # 前置依赖
npm install class-transformer --save
npm install es6-shim --save # 需要ES6支持,否则需要安装
1
2
3
2
3
- api 方法
plainToInstance
:将普通对象数组转换为class
数组
import {plainToInstance} from 'class-transformer';
let users = plainToInstance(User, userJson); // to convert user plain object a single user. also supports arrays
1
2
3
2
3
plainToClassFromExist
: 将普通对象数组转换为class
数组,并使用exist
对象中的属性填充class
对象的属性
const defaultUser = new User();
defaultUser.role = 'user';
// 如果 user 对象中存在 role 属性,则使用 user 对象中的 role 属性,否则使用默认的 role 属性值, 即 ’user‘。
let mixedUser = plainToClassFromExist(defaultUser, {id: 1, firstName: 'Mike', lastName: 'Bob'}); // mixed user should have the value role = user when no value is set otherwise.
1
2
3
4
5
2
3
4
5
instanceToPlain
: 实例转换为普通js对象
console.log(instanceToPlain(mixedUser))
// 普通js 对象 { id: 1, firstName: 'Mike', lastName: 'Bob', role: 'user'}
1
2
3
2
3
instanceToInstance
: 实例转换为新实例, 可以理解为cloneserialize
: 序列化为json格式deserialize
&deserializeArray
: 反序列化(数组)Exclude
: 忽略属性Expose
: 显示属性
import {Exclude, Expose} from 'class-transformer';
@Exclude()
export class User {
@Expose()
id: number;
@Expose()
email: string;
password: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Type
: 类型转换Transform
: 数据转换@Transform(({ value, key, obj, type }) => value)
import {Type} from 'class-transformer';
export class User {
id: number;
email: string;
password: string;
// 将日期字符串转换为日期对象
@Type(() => Date)
registrationDate: Date;
@Type(() => Date)
@Transform(({value}) => moment(value), {toClassOnly: true})
date: Moment;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
🌙 总结
class-transformer
是一个用于类转换的库, 它提供了许多装饰器来帮助转换类实例和普通对象,如@Exclude
、@Expose
、@Type
、
@Transform
等。 通过使用这些装饰器, 我们可以轻松地将普通对象转换为类实例, 并且可以控制哪些属性被转换, 以及如何转换它们。
它还支持数组转换, 并且提供了许多其他功能, 使得类转换更加方便和灵活。