export interface InitFunc { (this: O): T; } export function initOnRead(target: any, propertyKey: T, init: InitFunc) { if (target.hasOwnProperty(propertyKey)) { return; } Object.defineProperty(target, propertyKey, { configurable: true, get(): T { const data = init.call(target); delete target[propertyKey]; target[propertyKey] = data; return data; }, set(v: T) { delete target[propertyKey]; target[propertyKey] = v; }, }); } export function InitOnReadDecorator(init: InitFunc): PropertyDecorator { return (target: O, propertyKey: T) => { initOnRead(target, propertyKey as any, init); }; }