简体   繁体   English

如何使用类转换器将 typescript class 转换为普通 javascript object

[英]How to convert typescript class to plain javascript object with class-transformer

I've some typescript classes instances in my angular app that I've to save to firebase.我的 angular 应用程序中有一些 typescript 类实例,我必须保存到 firebase。 Firebase isn't supporting custom classes, so I found this: https://github.com/typestack/class-transformer that seems well fitted for me. Firebase 不支持自定义类,所以我发现这个: https://github.com/typestack/class-transformer似乎很适合我。

So now I'm creating my object, and trying to convert it.所以现在我正在创建我的 object,并尝试对其进行转换。

Here is my object.这是我的 object。

export class Trip {
  id: string;
  owner: string;
  name: string;
  @Type(() => Date)
  startDate: Date;
  @Type(() => Date)
  endDate: Date | undefined;
  coverImageUrl: string;

  @Type(() => Itinerary)
  itinerary: Itinerary;

  constructor() {
    this.itinerary = new Itinerary();
  }
}

export class Itinerary {
  @Type(() => ItineraryStats)
  stats: ItineraryStats;
  @Type(() => Step, {
    discriminator: {
      property: '__type',
      subTypes: [
        { value: ActivityStep, name: 'ActivityStep' },
        { value: NightStep, name: 'NightStep' },
        { value: PointOfInterest, name: 'PointOfInterest' },
        { value: TravelStep, name: 'TravelStep' },
      ],
    },
  })
  steps: Step[];

  constructor() {
    this.steps = Step[0];
    this.stats = new ItineraryStats();
  }
}

export class ItineraryStats {
  ///In days
  duration: number;
  //in hours
  driveTime: number;
  //in kilometers
  driveDistance: number;

  averageDriveDistancePerDay(): number {
    return this.driveDistance / this.duration;
  }
  averageDriveTimePerDay(): number {
    return this.driveTime / this.duration;
  }
}


export abstract class Step {
  @Type(() => Date)
  start: Date;

  @Type(() => Date)
  end: Date;
  duration: number;
  enforcedStartStop: boolean;
  warning: string;
}

export class ActivityStep extends StopStep {
  duration: number;

  constructor() {
    super();
    this.id = Guid.newGuid();
  }
}


export class NightStep extends StopStep {
  nightNumber: number;
  numberOfNight: number;
}

export class PointOfInterest {
  @Type(()=>PointOfInterest)
  type: PointOfInterest;
}


export class TravelStep extends Step {
  @Type(() => TravelMode)
  Mode: TravelMode;
  PolyLines: string;
}

I'm creating one "trip" and trying to convert it:我正在创建一个“旅行”并尝试对其进行转换:

const trip = new Trip();
trip.owner= firebase.auth().currentUser.uid;
trip.name= action.name;
trip.startDate = action.startDate,
trip.endDate = action.endDate;
console.log(trip);
const converted = classToPlain(trip)

But I get this:但我明白了:

ERROR TypeError: Cannot read property 'constructor' of undefined
    at TransformOperationExecutor.js:207
    at Array.find (<anonymous>)
    at TransformOperationExecutor.transform (TransformOperationExecutor.js:207)
    at TransformOperationExecutor.transform (TransformOperationExecutor.js:266)
    at ClassTransformer.classToPlain (ClassTransformer.js:10)
    at classToPlain (index.js:8)
    at Object.toFirestore (trips.firestore.ts:16)
    at ma (index.cjs.js:15983)
    at n.set (index.cjs.js:15359)
    at AngularFirestoreDocument.set (angular-fire-firestore.js:512)

The object I just created:我刚刚创建的 object: 在此处输入图像描述

I guess either my object is in an improper state or I've something poorly defined, but I can't find what?我猜我的 object 是不正确的 state 或者我的定义不明确,但我找不到什么?

The error lies in the definition of Itinerary , more specifically the code line this.steps = Step[0];错误在于Itinerary的定义,更具体地说是代码行this.steps = Step[0]; which sets the variable to undefined and most likely wasn't intentional.它将变量设置为未定义,很可能不是故意的。 The class-transformer library can deal with property steps being an empty array, array of steps, or not existing in the first place but crashes when the value is set to undefined. class-transformer器库可以处理属性steps是一个空数组、步骤数组或首先不存在但当值设置为未定义时崩溃。

export class Itinerary {
  @Type(() => ItineraryStats)
  stats: ItineraryStats;
  @Type(() => Step, {
    discriminator: {
      property: '__type',
      subTypes: [
        { value: ActivityStep, name: 'ActivityStep' },
        { value: NightStep, name: 'NightStep' },
        { value: PointOfInterest, name: 'PointOfInterest' },
        { value: TravelStep, name: 'TravelStep' },
      ],
    },
  })
  steps: Step[];

  constructor() {
    // Step[0] causes the crash, because its undefined, either dont set it or 
    // set it to this.steps = []
    this.steps = Step[0]; 
    this.stats = new ItineraryStats();
  }
}

More details: Due to the use of discriminators on property steps the corresponding logic kicked in and compared the constructors defined under subTypes , with the constructor of the current value to find the correct subtype name:更多细节:由于在属性steps上使用了鉴别器,相应的逻辑启动并将subTypes下定义的构造函数与当前值的构造函数进行比较以找到正确的子类型名称:

    if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
      subValue[targetType.options.discriminator.property] = targetType.options.discriminator.subTypes.find(
        subType => subType.value === subValue.constructor
      ).name;
    }

link to github 链接到 github

Step[0] being undefined eventually made this line subValue.constructor crash. Step[0]未定义最终使这一行subValue.constructor崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript 如何使用类转换器初始化混合类型数组 - Typescript How to initialize mixed type array with class-transformer 如何通过类变压器识别孩子 object? | Nest.js - how to identify a child object by class-transformer ? | Nest.js 如何使用 TypeScript 中的“class-transformer”将 API 请求的响应转换为类实例? - How to transform response from API request into class instance with `class-transformer` in TypeScript? 在nestjs中使用类转换器时如何等待? - how to await when using class-transformer in nestjs? 如何在嵌套组件中使用“类转换器”访问“组” - How to access "groups" using "class-transformer" in nested components 将javascript普通对象转换为模型类实例 - convert javascript plain object into model class instance 我们需要借助类转换器将 JS object 反序列化为 Model 模式 - We need to deserialize in JS object to Model schema with help of class-transformer 如何使用普通的旧版JavaScript JavaScript以不中断访问对象的方式导出TypeScript类 - How to export a TypeScript class in a way that won't disrupt accessing the object using plain old vanilla JavaScript 将 javascript 类实例转换为普通对象保留方法 - Convert javascript class instance to plain object preserving methods 如何在TypeScript中创建可在普通JavaScript中使用的全局名称空间/类? - How to create global namespace/class in TypeScript that can be used in plain JavaScript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM