export class Settings { readonly name: string; readonly props: T; private _onChange?: (props: Partial) => void; constructor(props: T, name: string = "settings") { this.props = props; this.name = name; } getProps(): T { return this.props; } setProps(props: Partial): this { Object.keys(props).forEach(p => ((this.props as any)[p] = props[p])); this._onChange && this._onChange(props); return this; } getProp(key: K): T[K] { return (this.props)[key]; } setProp(key: K, value: T[K]): this { (this.props)[key] = value; const props: Partial = {}; props[key] = value; this._onChange && this._onChange(props); return this; } onChange(callback: (props: Partial) => void): this { this._onChange = callback; return this; } } // Test: npx ts-node src/settins.ts // const x = { n: 2, s: "s" }; // const s = new Settings(x); // s.setProps({ n: 3 }); // console.log(typeof s.getProp("n")); // number // console.log(typeof s.getProp("s")); // string // s.setProps(JSON.parse(window.localStorage[s.name])); // s.onChange(() => (window.localStorage[s.name] = JSON.stringify(s.props))); // const settingsInit = JSON.parse(localStorage.getItem("settings") ?? "{}"); // const settings = new Settings(settingsInit); // settings.onChange((props) => localStorage.setItem("settings", JSON.stringify(props)));