Issue
I'm new in typescript, and I'm trying to rewrite our application from es2016 to TypeScript. My task is to have a class with data property and make each element from data object available as class property.
I get stuck on this JavaScript code:
for(let key in this.data) {
Object.defineProperty(this, key, {
get: function(value:any) { return this.data[key]; },
set: function(value:any) {
if (this.data[key] !== value) {
this.data[key] = value;
this.updatedKeys.push(key);
}
},
});
}
It is pretty easy to use getter/setters for typescript, but i get confused if i can create them dynamically?
interface IData {
id: number;
[propName: string]: any;
}
class Model {
protected updatedKeys:string[] = [];
baseUrl:string = null;
data:IData;
fields:IData;
constructor(data:IData={id:null}, fields:IData={id:null}) {
super();
this.data = data;
this.fields = fields;
for(let key in this.data) {
Object.defineProperty(this, key, {
get: function(value:any) { return this.data[key]; },
set: function(value:any) {
if (this.data[key] !== value) {
this.data[key] = value;
this.updatedKeys.push(key);
}
},
});
}
}
}
tsc -t ES2016 --lib "es2016","dom" models.ts
will give this error:
models.ts(33,40): error TS2345: Argument of type '{ get: (value: any) => any; set: (value: any) => void; }' is not assignable to parameter of type 'PropertyDescriptor & ThisType<any>'.
Type '{ get: (value: any) => any; set: (value: any) => void; }' is not assignable to type 'PropertyDescriptor'.
Types of property 'get' are incompatible.
Type '(value: any) => any' is not assignable to type '() => any'.
And I don't know how to get rid of this problem.
Solution
thanks to the https://github.com/epicgirl1998, she helped me to find the solution. I'll post it here:
the error is that the getter has a value parameter even though getters aren't passed any value
i replaced it with get: function() { return this.data[key]; }, and now the only error is that there's a super call in the class which is only needed if the class extends another class
also, this inside the accessors doesn't refer to the class instance, but using arrow functions for them should fix it
try this:
interface IData {
id: number;
[propName: string]: any;
}
class Model {
protected updatedKeys:string[] = [];
baseUrl:string = null;
data:IData;
fields:IData;
constructor(data:IData={id:null}, fields:IData={id:null}) {
this.data = data;
this.fields = fields;
for(let key in this.data) {
Object.defineProperty(this, key, {
get: () => { return this.data[key]; },
set: (value:any) => {
if (this.data[key] !== value) {
this.data[key] = value;
this.updatedKeys.push(key);
}
},
});
}
}
}
Answered By - Vlad
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.