typescript - Using Object Destructuring to Assign Class Members -


i in process of converting come legacy code typescript project. project contains number of custom classes written in pure javascript follow same pattern of having constructor takes in config object can have many configuration options defined within it.

i've been toying how define allowed config properties in typescript , haven't yet come solution i'm entirely happy with. started declaring interface config, allows me define config options available doesn't defaulting them - have copy config interface twice or more both definition , initialisation. (think i) want use object destrcuturing define class members once default values , not have worry after e.g:

export interface myclassconfig {     propa: string;     propb: boolean; }  export class myclass {     private propa: string = 'defautvalue';     private propb: boolean;      constructor (config: myclassconfig) {         { propa, propb } = config;     } } 

which initialised like:

let mc = new myclass({ propb: false });   //mc.propa == 'defaultvalue', mc.propb === false 

i don't requires me copy property names multiple times though. can suggest nice clean way achieve this?

i don't see big issue of adding config object member object class. current solutions of latest typescript version aren't nice , on complicates simple this. similar has been suggested before combining destructuring parameter properties. proposal 2 years old. however, there numerous ways above, not whether or not need access fields inside class well.

onto methods might solve above, given following interface...

interface iconfigopts {     propa: string,     propb: boolean     propc: number } 

...and class structure.

class config {      constructor(opts: iconfigopts) {         // object.assign(this, opts);         object.entries(opts).foreach((property: [string, any]) => {             object.defineproperty(this, property[0], {                 writable: true,                 value: property[1]             });         });     }      props() {         return object.getownpropertynames(this).map(key => ({[key]: this[key]}));     } } 

you can use object.assign (es5+), suggested frank, or object.defineproperty initialize member fields in constructor. latter gives option make properties writable or assign getters and/or setters.

you can create factory method properties types outside of class using creation of new instance of config class , interface:

const configfactory = (opts: iconfigopts) => new config(opts) config & iconfigopts;  const cfg = configfactory({     propa: 'propa',     propb: true,     propc: 5 });  let a: string = cfg.propa; // ok => defined 

but won't allow use this.propa in class type checking. cant (yet) dynamically bind typed class members class using destructures. , forces use this[key] instead.

if don't want access properties outside of class, can define method call properties name , use types validate defined types in given interface omits use of this[key] , returns given type:

prop<tkey extends keyof iconfigopts, tvalue extends iconfigopts[tkey]>(key: tkey): tvalue {     return this[key string]; } 

this ensures entered key exists in in interface using lookup keyof , returns correct type well.

let a: string = cfg.prop('propa'); // ok => defined let b: boolean = cfg.prop('propb'); // ok => defined let c: number = cfg.prop('propc'); // ok => defined  let d: number = cfg.prop('propd'); // fail => argument not assignable keyof iconfigopts let e: boolean = cfg.prop('propc'); // fail => type number not assignle type boolean 

the nice thing automatically binding (lots of) properties class not need edit destructure of object in given constructor match keys of object. e.g. propa changes propab. have change interface declaration.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -