@dynadok/class-transformer

中文文档
0.5.3发布于 2026/07/22MITTypeScriptESM + CJS零依赖近 30 天下载 4327

将平面javascript对象对类构造器进行适当的以装饰器为基础的转换/序列化/去串行化. Dynadok分叉 类变相器 0.5.1 有编译的快速路径,用于排除外相瓦列.

中文使用文档
文档目录35 节
  1. 目录
  2. 什么是类转换器 ⬆
  3. 安装 ⬆
  4. 节点.js ⬆
  5. 浏览器 ⬆
  6. 方法 ⬆
  7. 普通类 ⬆
  8. plain Toclass FromExist 软件 ⬆
  9. 类待处理 ⬆
  10. 类分类 ⬆
  11. 序列化 ⬆
  12. 拆除和拆除箭头 ⬆
  13. 执行类型安全的实例 ⬆
  14. 与嵌入对象合作 ⬆
  15. 提供多个类型选项 ⬆
  16. 曝光获取器和方法返回值 ⬆
  17. 显示不同名称的属性 ⬆
  18. 跳过特定属性 ⬆
  19. 跳过运行的依赖 ⬆
  20. 跳过类中的所有属性 ⬆
  21. 跳过私有属性, 或一些前缀属性 ⬆
  22. 使用组来控制被排除在外的财产 ⬆
  23. 使用版本控制暴露和排除的属性 ⬆
  24. 将日期字符串转换为日期对象 ⬆
  25. 工作数组 ⬆
  26. 其他数据转换 ⬆
  27. 基本用途 ⬆
  28. 高级用途 ⬆
  29. 其他装饰 ⬆
  30. 通用技术 ⬆
  31. 隐形类型转换 ⬆
  32. 如何处理循环参考? ⬆
  33. 带有角2 的示例 ⬆
  34. 样本 ⬆
  35. 发布注释 ⬆

类转换器

叉状通知 —— 说 @dynadok/class-transformer 是 Dynadok 维护的叉 类型/类-转换器 (基于v0.5.1). 它扩展已编译的快速路径支持 excludeExtraneousValues。 。 。 . 所有原始库的功劳都归TypeStack贡献者(MIT)所有.

Build Status codecov npm version

它的ES6和Typescript时代. 现在,你的工作 与课堂和建筑对象 比以往任何时候. 类转换器允许您将普通对象转换为某种类,反之亦然. 而且它允许根据标准序列化/去序列化对象. 这个工具在前端和后端都超级有用.

以角 2 为例使用 弹簧。 。 。 . 源代码可用 这里。 。 。 .

目录

什么是类转换器⬆

在 JavaScript 有两种对象:

  • 平方( 升) 对象
  • 类(构件)对象

平方物体是指具有下列特性的物体: Object 课. 有时会叫他们 字义 对象,当通过 {} 标注. 类对象是指具有自定义构造器,属性和方法的类. 通常通过 class 标注.

有什么问题吗?

有时你想将普通的 Javascript 对象转换为 ES6 类 没错. 例如,如果你从后端装入一个json, 一些 api 或者从json 文件, 在你后边 JSON.parse 你有一个普通的javascript对象, 而不是你的类.

例如,您在您的用户列表中 users.json 您正在装入 :

[
  {
    "id": 1,
    "firstName": "Johny",
    "lastName": "Cage",
    "age": 27
  },
  {
    "id": 2,
    "firstName": "Ismoil",
    "lastName": "Somoni",
    "age": 50
  },
  {
    "id": 3,
    "firstName": "Luke",
    "lastName": "Dacascos",
    "age": 12
  }
]

你有一个 User 类 :

export class User {
  id: number;
  firstName: string;
  lastName: string;
  age: number;

  getName() {
    return this.firstName + ' ' + this.lastName;
  }

  isAdult() {
    return this.age > 36 && this.age < 60;
  }
}

您假设您正在下载类型用户 User 从 users.json 文件并可能想要写入 以下代码:

fetch('users.json').then((users: User[]) => {
  // you can use users here, and type hinting also will be available to you,
  //  but users are not actually instances of User class
  // this means that you can't use methods of User class
});

您可以在此代码中使用 users[0].id,也可以使用 users[0].firstName 财务报告和审定财务报表 users[0].lastName。 。 。 . 但是,你无法使用 users[0].getName() 或者说 users[0].isAdult() 因为"用户"其实是 数组普通javascript对象,而不是用户对象的实例. 你居然骗了编译员 你说它的 users: User[]。 。 。 .

那怎么办? 怎样做一个 users 实例 User 对象而不是普通的 javascript 对象? 解决方案是创建用户对象的新实例并手动将所有属性复制到新对象. 但是一旦你有了更复杂的对象等级,事情可能会很快发生错误.

替代品? 是的,你可以使用类转换器。 这个图书馆的用意是帮助您绘制您的普通的javascript 对象为您所选的类.

这个库对于在你的API中曝光的模型也非常出色, 因为它提供了很好的工具 控制你的模型 正在你的API. 下面是一个例子,它将是什么样子:

fetch('users.json').then((users: Object[]) => {
  const realUsers = plainToClass(User, users);
  // now each user in realUsers is an instance of User class
});

现在你可以用 users[0].getName() 财务报告和审定财务报表 users[0].isAdult() 方法。 。 .

安装⬆

节点.js⬆

  1. 安装模块 :

    npm install class-transformer --save

  2. reflect-metadata shim 需要, 安装它:

    npm install reflect-metadata --save

    并且确保将它导入到一个全球性的地方,比如应用:

    import 'reflect-metadata';
    
  3. 使用ES6特性,如果您使用旧版本的节点.js,您可能需要安装es6-shim:

    npm install es6-shim --save

    并导入到一个全球性的地方, 如 app. ts :

    import 'es6-shim';
    

浏览器⬆

  1. 安装模块 :

    npm install class-transformer --save

  2. reflect-metadata shim 需要, 安装它:

    npm install reflect-metadata --save

    添加 <script> 在您头部反射-元数据 index.html数字 :

    <html>
      <head>
        <!-- ... -->
        <script src="node_modules/reflect-metadata/Reflect.js"></script>
      </head>
      <!-- ... -->
    </html>
    

    如果你使用角2,你应该已经安装了这个shim.

  3. 如果您正在使用系统.js, 您可能想要将此添加到 map 财务报告和审定财务报表 package 配置 :

    {
      "map": {
        "class-transformer": "node_modules/class-transformer"
      },
      "packages": {
        "class-transformer": { "main": "index.js", "defaultExtension": "js" }
      }
    }
    

方法⬆

普通类⬆

这种方法将普通的javascript对象转换为特定类的实例.

import { plainToClass } from 'class-transformer';

let users = plainToClass(User, userJson); // to convert user plain object a single user. also supports arrays

plain Toclass FromExist 软件⬆

这种方法将普通对象转换成实例,使用一个已经填充的对象,这是目标类的一个实例.

const defaultUser = new User();
defaultUser.role = 'user';

let mixedUser = plainToClassFromExist(defaultUser, user); // mixed user should have the value role = user when no value is set otherwise.

类待处理⬆

这种方法将您的类对象转换回普通的 Javascript 对象, 可以是 JSON.stringify 等会.

import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo);

类分类⬆

此方法将您的类对象转换为类对象的新实例 . 这可能会被当作你的物体的深克隆.

import { classToClass } from 'class-transformer';
let photo = classToClass(photo);

您也可以使用一个 ignoreDecorators 选项在变换选项中忽略您所使用所有装饰.

序列化⬆

您可以使用 serialize 方法 :

import { serialize } from 'class-transformer';
let photo = serialize(photo);

serialize 与数组和非数组同时工作.

拆除和拆除箭头⬆

你可以用Json的 deserialize 方法 :

import { deserialize } from 'class-transformer';
let photo = deserialize(Photo, photo);

使去区域化与数组配合,使用 deserializeArray 方法 :

import { deserializeArray } from 'class-transformer';
let photos = deserializeArray(Photo, photos);

执行类型安全的实例⬆

默认行为 plainToClass 方法是设置 全部 纯对象属性, 甚至是班级上没有规定的.

import { plainToClass } from 'class-transformer';

class User {
  id: number;
  firstName: string;
  lastName: string;
}

const fromPlainUser = {
  unkownProp: 'hello there',
  firstName: 'Umed',
  lastName: 'Khudoiberdiev',
};

console.log(plainToClass(User, fromPlainUser));

// User {
//   unkownProp: 'hello there',
//   firstName: 'Umed',
//   lastName: 'Khudoiberdiev',
// }

如果这种行为不适合你的需要,你可以使用 excludeExtraneousValues 选项 输入 plainToClass 方法时 显示所有类属性 作为一项要求.

import { Expose, plainToClass } from 'class-transformer';

class User {
  @Expose() id: number;
  @Expose() firstName: string;
  @Expose() lastName: string;
}

const fromPlainUser = {
  unkownProp: 'hello there',
  firstName: 'Umed',
  lastName: 'Khudoiberdiev',
};

console.log(plainToClass(User, fromPlainUser, { excludeExtraneousValues: true }));

// User {
//   id: undefined,
//   firstName: 'Umed',
//   lastName: 'Khudoiberdiev'
// }

与嵌入对象合作⬆

当你试图改变 已经嵌入物体的物体, 它需要知道你想要改变的物体类型. 由于Typescript还没有很好的反射能力, 我们应该隐含地说明每个财产包含的物体类型. 使用 @Type 装饰师.

假设我们有一张带相片的相册. 我们正在尝试将相册普通对象转换为类对象:

import { Type, plainToClass } from 'class-transformer';

export class Album {
  id: number;

  name: string;

  @Type(() => Photo)
  photos: Photo[];
}

export class Photo {
  id: number;
  filename: string;
}

let album = plainToClass(Album, albumJson);
// now album is Album object with Photo objects inside

提供多个类型选项⬆

如果被嵌入对象可以是不同类型,您可以提供额外的选项对象, 规定歧视者。 歧视者选项必须界定 property 带有子类型 对象的名称和可能 subTypes 被嵌入对象可以转换为。 子类型 有一个 value中,该类型和 name,可以与 property 歧视者.

假设我们有一张专辑 有一张顶级相片。 但是,这张照片可以是某些不同类型的. 我们正在尝试将相册平面对象转换成类对象。 普通对象输入必须定义 额外财产 __type。该属性在转换过程中默认删除 :

JSON 输入数字 :

{
  "id": 1,
  "name": "foo",
  "topPhoto": {
    "id": 9,
    "filename": "cool_wale.jpg",
    "depth": 1245,
    "__type": "underwater"
  }
}
import { Type, plainToClass } from 'class-transformer';

export abstract class Photo {
  id: number;
  filename: string;
}

export class Landscape extends Photo {
  panorama: boolean;
}

export class Portrait extends Photo {
  person: Person;
}

export class UnderWater extends Photo {
  depth: number;
}

export class Album {
  id: number;
  name: string;

  @Type(() => Photo, {
    discriminator: {
      property: '__type',
      subTypes: [
        { value: Landscape, name: 'landscape' },
        { value: Portrait, name: 'portrait' },
        { value: UnderWater, name: 'underwater' },
      ],
    },
  })
  topPhoto: Landscape | Portrait | UnderWater;
}

let album = plainToClass(Album, albumJson);
// now album is Album object with a UnderWater object without `__type` property.

提示:同样适用于具有不同子类型的数组. 此外,你可以说明 keepDiscriminatorProperty: true 在选项中将歧视者的财产也保留在相应的类别中.

曝光获取器和方法返回值⬆

您可以通过设置 @Expose() 这些获取器或方法的装饰器:

import { Expose } from 'class-transformer';

export class User {
  id: number;
  firstName: string;
  lastName: string;
  password: string;

  @Expose()
  get name() {
    return this.firstName + ' ' + this.lastName;
  }

  @Expose()
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

显示不同名称的属性⬆

如果你想揭露一些有不同名称的属性, 您可以通过指定 name 选项到 @Expose 装饰 :

import { Expose } from 'class-transformer';

export class User {
  @Expose({ name: 'uid' })
  id: number;

  firstName: string;

  lastName: string;

  @Expose({ name: 'secretKey' })
  password: string;

  @Expose({ name: 'fullName' })
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

跳过特定属性⬆

有时您想要在转换时跳过一些属性 . 可用 @Exclude 装饰 :

import { Exclude } from 'class-transformer';

export class User {
  id: number;

  email: string;

  @Exclude()
  password: string;
}

当你改变一个用户时 password 属性将被跳过而不包含在已改变的结果中.

跳过运行的依赖⬆

您可以控制您要排除财产的操作 。 使用 toClassOnly 或者说 toPlainOnly 选项:

import { Exclude } from 'class-transformer';

export class User {
  id: number;

  email: string;

  @Exclude({ toPlainOnly: true })
  password: string;
}

现在 password 财产仅在 classToPlain 操作。 反之亦然,请使用 toClassOnly 选项.

跳过类中的所有属性⬆

您可以跳过该类的所有属性, 并只披露那些是明确需要的:

import { Exclude, Expose } from 'class-transformer';

@Exclude()
export class User {
  @Expose()
  id: number;

  @Expose()
  email: string;

  password: string;
}

现在 id 财务报告和审定财务报表 email 将打开,在转换时将排除密码. 或者,您可以在转型期间设定排斥策略:

import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo, { strategy: 'excludeAll' });

在这种情况下,你不需要 @Exclude() 整个班级.

跳过私有属性, 或一些前缀属性⬆

如果您用前缀命名您的私有属性, 请用 _, (中文(简体) ), 然后,您也可以将此类属性排除在转换之外:

import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo, { excludePrefixes: ['_'] });

这将跳过开始的所有属性 _ 前缀. 您可以通过任意数量的前缀,所有从这些前缀开始的属性都会被忽略. 例如:

import { Expose, classToPlain } from 'class-transformer';

export class User {
  id: number;
  private _firstName: string;
  private _lastName: string;
  _password: string;

  setName(firstName: string, lastName: string) {
    this._firstName = firstName;
    this._lastName = lastName;
  }

  @Expose()
  get name() {
    return this._firstName + ' ' + this._lastName;
  }
}

const user = new User();
user.id = 1;
user.setName('Johny', 'Cage');
user._password = '123';

const plainUser = classToPlain(user, { excludePrefixes: ['_'] });
// here plainUser will be equal to
// { id: 1, name: "Johny Cage" }

使用组来控制被排除在外的财产⬆

您可以使用组来控制哪些数据将会被曝光,哪些不会被曝光 :

import { Exclude, Expose, classToPlain } from 'class-transformer';

export class User {
  id: number;

  name: string;

  @Expose({ groups: ['user', 'admin'] }) // this means that this data will be exposed only to users and admins
  email: string;

  @Expose({ groups: ['user'] }) // this means that this data will be exposed only to users
  password: string;
}

let user1 = classToPlain(user, { groups: ['user'] }); // will contain id, name, email and password
let user2 = classToPlain(user, { groups: ['admin'] }); // will contain id, name and email

使用版本控制暴露和排除的属性⬆

如果您正在构建一个具有不同版本的API,类转换器对此有极其有用的工具. 您可以控制在哪个版本中显示或排除您的模型的哪些属性 。 示例

import { Exclude, Expose, classToPlain } from 'class-transformer';

export class User {
  id: number;

  name: string;

  @Expose({ since: 0.7, until: 1 }) // this means that this property will be exposed for version starting from 0.7 until 1
  email: string;

  @Expose({ since: 2.1 }) // this means that this property will be exposed for version starting from 2.1
  password: string;
}

let user1 = classToPlain(user, { version: 0.5 }); // will contain id and name
let user2 = classToPlain(user, { version: 0.7 }); // will contain id, name and email
let user3 = classToPlain(user, { version: 1 }); // will contain id and name
let user4 = classToPlain(user, { version: 2 }); // will contain id and name
let user5 = classToPlain(user, { version: 2.1 }); // will contain id, name and password

将日期字符串转换为日期对象⬆

有时,您在普通的javascript对象中有一个以字符串格式接收的日期. 您想要从中创建一个真正的 Javascript Date 对象 . 您可以简单地将日期对象传递到 @Type 装饰 :

import { Type } from 'class-transformer';

export class User {
  id: number;

  email: string;

  password: string;

  @Type(() => Date)
  registrationDate: Date;
}

同样的技术可以使用 Number, (中文(简体) ), String, (中文(简体) ), Boolean 当您想要将您的值转换为这些类型时, 原始类型 .

工作数组⬆

当您使用数组时,您必须提供数组所包含对象的类型. 此类型,请在 @Type() 装饰 :

import { Type } from 'class-transformer';

export class Photo {
  id: number;

  name: string;

  @Type(() => Album)
  albums: Album[];
}

您也可以使用自定义的数组类型 :

import { Type } from 'class-transformer';

export class AlbumCollection extends Array<Album> {
  // custom array functions ...
}

export class Photo {
  id: number;

  name: string;

  @Type(() => Album)
  albums: AlbumCollection;
}

图书馆将自动处理适当的转换.

ES6号集 Set 财务报告和审定财务报表 Map 还要求 @Type 装饰 :

export class Skill {
  name: string;
}

export class Weapon {
  name: string;
  range: number;
}

export class Player {
  name: string;

  @Type(() => Skill)
  skills: Set<Skill>;

  @Type(() => Weapon)
  weapons: Map<string, Weapon>;
}

其他数据转换⬆

基本用途⬆

您可以使用 @Transform 装饰师. 例如,你想让自己的 Date 对象为 a moment 当您是对象时 将对象从平面转换成类 :

import { Transform } from 'class-transformer';
import * as moment from 'moment';
import { Moment } from 'moment';

export class Photo {
  id: number;

  @Type(() => Date)
  @Transform(({ value }) => moment(value), { toClassOnly: true })
  date: Moment;
}

现在当你打电话 plainToClass 并派遣一个明亮的、, 它将把相片对象中的日期值转换为瞬间日期. @Transform 装饰者还支持组和版本.

高级用途⬆

这个 @Transform 给装饰者提供了更多的参数,以便您配置您想要如何完成转换 .

@Transform(({ value, key, obj, type }) => value)
参数说明
value变相前的财产价值.
key被改造后的财产名称.
obj变相源对象.
type变相类型.
options选项对象传递到转换方法.

其他装饰⬆

签署示例说明
@TransformClassToPlain@TransformClassToPlain({ groups: ["user"] })用类"ToPlain"来转换方法返回并曝光类中的属性.
@TransformClassToClass@TransformClassToClass({ groups: ["user"] })以类ToClass来转换方法返回并曝光类中的属性.
@TransformPlainToClass@TransformPlainToClass(User, { groups: ["user"] })用平原ToClass来转换方法返回,并曝光类中的属性.

上述装饰者接受一个任择论点: Class Transform 选项 - 组,版本,名称等变换选项

一个例子是:

@Exclude()
class User {
  id: number;

  @Expose()
  firstName: string;

  @Expose()
  lastName: string;

  @Expose({ groups: ['user.email'] })
  email: string;

  password: string;
}

class UserController {
  @TransformClassToPlain({ groups: ['user.email'] })
  getUser() {
    const user = new User();
    user.firstName = 'Snir';
    user.lastName = 'Segal';
    user.password = 'imnosuperman';

    return user;
  }
}

const controller = new UserController();
const user = controller.getUser();

页:1 user 变量只包含第一个Name, lastName, 电子邮件属性, 因为它们是 被曝光的变量。 电子邮件属性也暴露了,因为我们对组"用户. email"进行了感动.

通用技术⬆

通用不支持, 因为 TypeScript 还没有很好的反射能力 . 一旦TypeScript团队为我们提供了更好的运行时间类型反射工具,将实施通用. 有一些微软,无论你可以用, 也许可以解决你的问题. 检查这个例子 .

隐形类型转换⬆

页:1 如果您同时使用类验证器和类转换器, 您可能不会启用此功能 .

根据Typescript提供的类型信息,允许内置类型之间的自动转换. 默认禁用 .

import { IsString } from 'class-validator';

class MyPayload {
  @IsString()
  prop: string;
}

const result1 = plainToClass(MyPayload, { prop: 1234 }, { enableImplicitConversion: true });
const result2 = plainToClass(MyPayload, { prop: 1234 }, { enableImplicitConversion: false });

/**
 *  result1 will be `{ prop: "1234" }` - notice how the prop value has been converted to string.
 *  result2 will be `{ prop: 1234 }` - default behaviour
 */

如何处理循环参考?⬆

循环引用被忽略. 比如说,如果你在改变阶级 User 包含属性 photos 类型 Photo, (中文(简体) ), 财务报告和审定财务报表 Photo 包含链接 user 发送给其父母 User,则 user 将在转换时被忽略. 循环引用不仅仅在 classToClass 操作.

带有角2 的示例⬆

假设您想要下载用户, 希望自动将其映射到 User 课.

import { plainToClass } from 'class-transformer';

this.http
  .get('users.json')
  .map(res => res.json())
  .map(res => plainToClass(User, res as Object[]))
  .subscribe(users => {
    // now "users" is type of User[] and each user has getName() and isAdult() methods available
    console.log(users);
  });

您也可以输入一个类 ClassTransformer 作为服务于 providers,并使用其方法.

以角 2 为例使用 弹簧。 。 。 . 源代码为 这里。 。 。 .

样本⬆

看看里面的样本 ./样本 更多实例 诸用相.

发布注释⬆

参见关于突破更改和发布注释的信息 这里。 。 。 .

版本与发布记录

@dynadok/class-transformer 共发布 2 个版本,首次发布于 2026/07/21;过去 12 个月发布了 2 个版本。

版本发布日期距今
0.5.3latest2026/07/223 个月前
0.5.22026/07/213 个月前

关于 @dynadok/class-transformer 的常见问题

@dynadok/class-transformer 是什么?

将平面javascript对象对类构造器进行适当的以装饰器为基础的转换/序列化/去串行化. Dynadok分叉 类变相器 0.5.1 有编译的快速路径,用于排除外相瓦列.

如何安装 @dynadok/class-transformer?

在项目目录运行 npm install @dynadok/class-transformer,或使用 pnpm add / yarn add / bun add。

@dynadok/class-transformer 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dynadok/class-transformer 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@dynadok/class-transformer 可以商用吗?

@dynadok/class-transformer 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dynadok/class-transformer 的下载量有多少?

根据 npm 官方下载统计,@dynadok/class-transformer 在 2026/10/13 – 2026/11/11 这 30 天内被下载 4,327 次,日均约 144 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dynadok/class-transformer 还在维护吗?

最新版本 0.5.3 发布于 2026/07/22(3 个月前);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/07/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。