Как использовать Immutable JS с типизированными классами ES6?
Скажем, у меня есть классы Task
и TaskGroup
class Task{
constructor(public text:string){}
}
class TaskGroup {
constructor(public title:string = "new task group", public tasks:Task[] = []){}
}
Затем в моей службе Angular 2 я создам неизменяемый список групп задач
@Injectable()
class TaskService {
taskGroups:Immutable.List<TaskGroup>;
constructor() {
this.taskGroups = Immutable.List<TaskGroup>([new TaskGroup("Coding tasks")]);
}
}
Таким образом, только список групп задач является неизменным. Все, что внутри, - нет. Даже если я делаю Immutable.fromJS(...)
вместо Immutable.List<Board>(...)
, вложенные объекты представляют собой простые объекты JavaScript Javascript.
Неизменяемый JS не предполагает наследование класса (Наследование от объекта с неизменяемым ES6 # 562)
//can't do this!
class TaskGroup extends Immutable.Map<string, any>{
constructor(public title:string = "new task group", public tasks:Task[]){}
}
//it complained about the class not having methods like set, delete etc
Итак, как создать объекты Immutable класса?
Ответы
Ответ 1
Вы можете сделать следующее:
const TodoRecord = Immutable.Record({
id: 0,
description: "",
completed: false
});
class Todo extends TodoRecord {
id:number;
description:string;
completed: boolean;
constructor(props) {
super(props);
}
}
let todo:Todo = new Todo({id: 1, description: "I'm Type Safe!"});
Не идеально, но работает.
Это происходит из этого замечательного сообщения в блоге:
https://blog.angular-university.io/angular-2-application-architecture-building-flux-like-apps-using-redux-and-immutable-js-js/
Ответ 2
Вы можете сделать обертку с Immutable, как указано в этом учебнике:
import { List, Map } from 'immutable';
export class TodoItem {
_data: Map<string, any>;
get text() {
return <string> this._data.get('text');
}
setText(value: string) {
return new TodoItem(this._data.set('text', value));
}
get completed() {
return <boolean> this._data.get('completed');
}
setCompleted(value: boolean) {
return new TodoItem(this._data.set('completed', value));
}
constructor(data: any = undefined) {
data = data || { text: '', completed: false, uuid: uuid.v4() };
this._data = Map<string, any>(data);
}
}
Надеюсь, это поможет!;)