0

Just imagine I have 2 html tables next to each other. Each table has an array of unassigned pupils or assigned pupils for a certain test. With 2 buttons you can move those checkbox-selected pupils to the other html table.

The pupils in both html tables have nearly the same properties.

When I use Object.Assign then I get an compile error:

properties gradeScorePairs is missing in type {} and UnAssignedPupil

To fix that error I just copy/paste the same properties on both objects...

Thats a workaround but not solution for me. I use Typescript 2 and transpile to ES5.

What possibilities do I have with object.assign and different types for source/target to solve this problem?

AssignedPupil.ts

import { GradeScorePair } from './gradeScorePair';
export class AssignedPupil {

    constructor(obj: any) {
        this.id = obj.id;
        this.name = obj.firstName + " " + obj.lastName;
    }

    id: number;
    name: string;
    gradeScorePairs: GradeScorePair[];
    isSelected: boolean;
    selectedGradeScorePair: GradeScorePair;
}

UnAssignedPupil.ts

import { GradeScorePair } from './gradeScorePair';
export class UnAssignedPupil {

    constructor(obj: any) {
        this.id = obj.id;
        this.name = obj.firstName + " " + obj.lastName;
    }

    id: number;
    name: string;
    // gradeScorePairs: GradeScorePair[]; // don`t need it on the unassigned html table
    isSelected: boolean;
    // selectedGradeScorePair: GradeScorePair; // don`t nee it on the unassigned html table
}

  unassignPupil() {
    var i = this.assignedPupils.length;
    while (i--) {
      var p = this.assignedPupils[i];
      if (p.isSelected) {
        let assignedPupil: AssignedPupil = this.assignedPupils.splice(i, 1)[0];
        let unAssignedPupil: UnAssignedPupil = Object.assign({}, assignedPupil);
        unAssignedPupil.isSelected = false;
        this.unAssignedPupils.push(unAssignedPupil);
      }
    }
  }

  assignPupil() {
    var i = this.unAssignedPupils.length;
    while (i--) {
      var p = this.unAssignedPupils[i];
      if (p.isSelected) {
        let pupilToAssign: UnAssignedPupil = this.unAssignedPupils.splice(i, 1)[0];
        let assignedPupil: AssignedPupil = Object.assign({}, pupilToAssign);

        // Difference are these 2 lines of code
        assignedPupil.gradeScorePairs = this.gradeScorePairs;
        assignedPupil.selectedGradeScorePair = null;

        assignedPupil.isSelected = false;
        this.assignedPupils.push(assignedPupil);
      }
    }
  }
4

1 回答 1

2

你可以告诉编译器这个空对象的类型是AssignedPupil

let assignedPupil: AssignedPupil = Object.assign({} as AssignedPupil, pupilToAssign);

这将清除错误。

问题是,当你这样做时,你不会真正拥有 class 的实例AssignedPupil,你将拥有一个具有相同属性的对象。由于打字稿的鸭式打字性质,
您不会有错误。

如果您打算仅将该类用作数据对象,那么您很好(但为什么不只使用接口?),但是如果您打算拥有类方法,那么变量assignedPupil将没有这些方法。


编辑

一个例子:

class Point {
    constructor(public x: number, public y: number) { }

    distance(other: Point) {
        return Math.sqrt(Math.pow((this.x - other.x), 2) + Math.pow((this.y - other.y), 2));
    }

    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

let a1 = new Point(0, 0);
console.log(a1.x); // 0
console.log(a1); // Point {x: 0, y: 0}
console.log(a1.toString()); // (0, 0)

let a2 = Object.assign({} as Point, a1);
console.log(a2.x); // 0
console.log(a2); // Object {x: 0, y: 0}
console.log(a2.toString()); // [object Object]

console.log(a1.distance(a2)); // 0
console.log(a2.distance(a1)); // Uncaught TypeError: a2.distance is not a function

操场上的代码

于 2016-10-09T20:52:34.987 回答