Skip to content

[question] Dynamic getters and settings for classes #17340

@vladyslav2

Description

@vladyslav2

Hello.

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.

Thank for help in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions