#typescript #typescript2.0
#typescript #typescript2.0
Вопрос:
Только представьте, что у меня есть 2 HTML-таблицы рядом друг с другом. Каждая таблица содержит массив неназначенных учеников или назначенных учеников для определенного теста. С помощью 2 кнопок вы можете переместить эти выбранные флажком ученики в другую таблицу html.
Ученики в обеих таблицах html имеют почти одинаковые свойства.
Когда я использую Object.Назначьте, затем я получаю ошибку компиляции:
properties gradeScorePairs is missing in type {} and UnAssignedPupil
Чтобы исправить эту ошибку, я просто копирую / вставляю одни и те же свойства для обоих объектов…
Это обходной путь, но не решение для меня. Я использую Typescript 2 и переношу в ES5.
Какие возможности у меня есть с object.assign и различными типами для источника / цели для решения этой проблемы?
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);
}
}
}
Ответ №1:
Вы можете сообщить компилятору, что этот пустой объект имеет тип AssignedPupil
:
let assignedPupil: AssignedPupil = Object.assign({} as AssignedPupil, pupilToAssign);
Это устранит ошибку.
Дело в том, что при этом у вас на самом деле не будет экземпляра class AssignedPupil
, у вас будет объект с теми же свойствами.
У вас не будет ошибок из-за того, что typescript использует типизацию с уткой.
Если вы собираетесь использовать этот класс только как объект данных, тогда все в порядке (но почему бы просто не использовать интерфейсы?), Но если вы планируете использовать методы класса, тогда переменная 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
Комментарии:
1. Оба объекта pupil на данный момент являются просто объектами данных.
2. Поэтому приведите его к
AssignedPupil
, и ошибка исчезнет. Но если это так, то нет необходимости в классах, используйте интерфейсы.3. Я пришел из C #, будучи новичком. НО интерфейсы не могут быть созданы, и я все еще создаю эти неназначенные / назначенные объекты из данных сервера, поэтому мне нужно создать оба типа объектов из json.
4. Вы инициируете только часть объектов. Вы можете сделать:
Object.assign(new AssignedPupil(), pupilToAssign)
который создаст экземпляр newAssignedPupil
, а затем присвоит значения, но вам нужно будет иметь дело с пустым конструктором.