namespace Leaf { export interface PropertyDefination { get?: (cache: PropertyCache) => T set?: (value: T, cache: PropertyCache) => void value?: T } export interface PropertyCache { [index: string]: any value?: T } export class Property { static define(who: any, name: string, def: PropertyDefination): T { let cache: PropertyCache = {} if (who[name]) cache.value = who[name] if (def.value) cache.value = def.value; let getFn = (cache: PropertyCache) => { return cache.value } let setFn = (value: T, cache: PropertyCache) => { cache.value = value return cache.value } let getIt = def.get || getFn let setIt = def.set || setFn Object.defineProperty(who, name, { get: () => { return getIt(cache) }, set: (v: T) => { return setIt(v, cache) } }) return def.value || null } // For IE using with will cause problem static withProps(who: any) { return new WithProperty(who) } } export class WithProperty { constructor(public who: any) { } public define(name: string, def: PropertyDefination) { Property.define(this.who, name, def) return this } } }