NestJs – CQRS – 寻找将对象作为构造函数参数传递的简单方法(从DTO到命令)

huangapple go评论82阅读模式
英文:

NestJs - CQRS - Looking for a simple way to pass an object as constructor parameters (From a DTO to a command)

问题

以下是您要翻译的部分:

我想要按照以下方式初始化一个命令:

    const command = new CreateProductCommand(payload);
    
    // 在另一个文件中
    export class Payload {
        public readonly type: string;
        public readonly name?: string;
    }

我的命令定义如下:

    export class CreateProductTypeACommand {
        public readonly name?: string;
    }

我尝试在构造函数中创建一个抽象命令来实现这个:

    export class AbstractCommand<T> implements ICommand {
        constructor(args: T) {
            Object.assign(this, args);
        }
    }
    
    // 在另一个文件中
    export class CreateProductTypeACommand extends AbstractCommand<CreateProductTypeACommand> {
        public readonly name?: string;
    }

但这并不起作用:子类的构造函数会覆盖父类的构造函数,`name` 的值被覆盖为 `undefined`。而且对象最终会具有 `type` 字段。

有什么想法吗?我宁愿不在我的命令类中放入任何样板代码或定义一个 `CreateProductTypeACommandArgs` 类型。
英文:

I would like to initialize a Command as Follows:

const command = new CreateProductCommand(payload);

// In another file
export class Payload {
    public readonly type: string;
    public readonly name?: string;
}

where my Command is defined like this:

export class CreateProductTypeACommand {
    public readonly name?: string;
}

I have tried create an abstract command to do this in the constructor:

export class AbstractCommand&lt;T&gt; implements ICommand {
    constructor(args: T) {
        Object.assign(this, args);
    }
}

// in another file
export class CreateProductTypeACommand extends AbstractCommand&lt;CreateProductTypeACommand&gt; {
    public readonly name?: string;
}

But this dosen't work: the child's constructor overrides the parents and the value for name gets overridden by undefined . Also the object ends up having the type field.

Any idea? I would rather not put any boiler plate code in my command classes or define a CreateProductTypeACommandArgs type.

答案1

得分: 1

I had a similar problem and what I ended up doing was using plainToClass from the class-transformer package.

For example

import { ClassConstructor, plainToClass } from "class-transformer";

// A neat utility function to check you supply all class properties
function map<T, V extends T>(cls: ClassConstructor<T>, plain: V): T {
  return plainToClass(cls, plain);
}

function doStuff() {
      const newProfile = {
        description: "my-description",
        name: "my-name",
        recentLocation: { lat: 1, lon: 2 },
        userId: "my-user-id",
      };

      const command = map(CreateProfileCommand, newProfile);
      ...
}
英文:

I had a similar problem and what I ended up doing was using plainToClass from the class-transformer package.

For example

import { ClassConstructor, plainToClass } from &quot;class-transformer&quot;;

// A neat utility function to check you supply all class properties
function map&lt;T, V extends T&gt;(cls: ClassConstructor&lt;T&gt;, plain: V): T {
  return plainToClass(cls, plain);
}

function doStuff() {
      const newProfile = {
        description: &quot;my-description&quot;,
        name: &quot;my-name&quot;,
        recentLocation: { lat: 1, lon: 2 },
        userId: &quot;my-user-id&quot;,
      };

      const command = map(CreateProfileCommand, newProfile);
      ...
}

huangapple
  • 本文由 发表于 2023年4月13日 16:18:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003191.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定