Какова цель Object.assign () в конструкторе объекта Typescript? - PullRequest
2 голосов
/ 09 апреля 2019

Где-то по пути я добавил конструктор в свой класс Todo:

export class Todo {
  id: number;
  title: string;
  complete: boolean = false;
  editMode: boolean = false;

  constructor(values: Object = {}) {
    Object.assign(this, values);
  }
}

Я не понимаю назначение кода в конструкторе.

Кажется, что мое приложение работает как с ним, так и без него, но я не решаюсь удалить код

Какова цель Object.assign (...) в этом конструкторе?

Ответы [ 3 ]

1 голос
/ 09 апреля 2019

Этот метод позволяет легко добавлять значения параметров класса в соответствующие поля класса, где класс реализует этот интерфейс или, по крайней мере, имеет частичную имплантацию этого интерфейса.

interface IPerson {
  firtName: string;
  lastName: string;
}

class Person implements IPerson {
  public firtName!: string;
  public lastName!: string;

  constructor(params: IPerson) {
    Object.assign(this, params);
  }
}

Ваше приложениеработает, потому что вы, кажется, реализовали это таким образом, что также достаточно значения обратного вызова values.

Основная проблема с этим хаком заключается в том, что Object.assign не является безопасным типом .Таким образом, использование его таким образом противоречит точке зрения TypeScript.

Если вы хотите сделать это безопасным для типов способом, вам лучше использовать пользовательскую реализацию, в которой тип проверен правильно.Примерно так:

type PDM = PropertyDescriptorMap;

export class ClassSAssign<T> {
  constructor(private objectToSpread: T, private klass: T) {}

  private propertyDescriptorOptions = {
    enumerable: true,
    writable: true
  };

  public apply(): void {
    const map = this.getPropertiesDescriptorMap();
    Object.defineProperties(this.klass, map);
  }

  private getPropertiesDescriptorMap(): PDM {
    return Object.entries(this.objectToSpread).reduce(
      (obj: PDM, entry) => this.getPropertyDescriptorMap(obj, entry),
      {}
    );
  }

  private getPropertyDescriptorMap(obj: PDM, [key, value]: [string, any]): PDM {
    return {
      ...obj,
      [key]: {
        value,
        ...this.propertyDescriptorOptions
      }
    };
  }
}

и вы можете использовать эту утилиту следующим образом:

class Person implements IPerson {
  public firtName!: string;
  public lastName!: string;

  constructor(params: IPerson) {
    new ClassSAssign(params, this).apply();
  }
}

Если вы не хотите / не хотите использовать вышеперечисленное, я предлагаю вам по адресухотя бы добавьте некоторую строгость типов, чтобы защитить ваш класс от того, какие значения могут быть переданы ему

interface IToDo {
  id?: number;
  title?: string;
}

export class Todo implements IToDo {
  public id?: number;
  public title?: string;
  public complete: boolean = false;
  public editMode: boolean = false;

  constructor(values?: IToDo) {
    Object.assign(this, values);
  }
}
1 голос
/ 09 апреля 2019

Object.assign присваивает все свойства второго аргумента первому аргументу.

Что делает код, если вы передаете объект в конструктор, он назначит эти свойства объекту, который являетсяБыть сделанным.Так, например:

const todo = new Todo({ id: 1, title: 'hello' });
console.log(todo.title); // 'hello'

Редактировать: поскольку Object.assign не является типобезопасным, вы, вероятно, должны иметь конструктор, принимающий что-то более конкретное, чем просто Object.Я бы предложил создать интерфейс для него.

0 голосов
/ 09 апреля 2019

Это просто объединение двух объектов this и values. Согласно MDN

Метод Object.assign() используется для копирования значений всех перечисляемых собственных свойств из одного или нескольких исходных объектов в целевой объект. Он вернет целевой объект.

Используется для создания поверхностной копии объекта и объединения его свойств с this, который является экземпляром Todo. В заданном вами коде this целевой объект. Рассмотрим приведенный ниже пример

let target = {a:1,b:2};
Object.assign(target,{x:"new prop 1",y:"new prop 2"});
console.log(target) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...