declare function setmetatable ( obj , meta ) ; declare var __get_call_undefined__ ; declare var __set_call_undefined__ ; module JS { export class Object { constructor ( private obj = { } ) { this . __index = function ( _this , indx ) : any { const val = _this . obj [ indx ] ; switch ( typeof ( val ) ) { case 'number' : return new Number ( val ) ; case 'string' : return new String ( val ) ; case 'table' : return new Object ( val ) ; } return val ; } ; this . __newindex = function ( _this , indx , val ) : void { _this . obj [ indx ] = val ; } ; } public static create ( proto ) { if ( ! proto ) { throw new Error ( 'Prototype can\'t be undefined or null' ) ; } const obj = < any > { } ; obj . __index = __get_call_undefined__ ; obj . __proto = proto ; obj . __newindex = __set_call_undefined__ ; setmetatable ( obj , obj ) ; if ( obj . constructor ) { obj . constructor ( ) ; } return obj ; } public static freeze ( obj ) { obj . __newindex = function ( table ) { throw new Error ( 'Object is read-only' ) ; } ; setmetatable ( obj , obj ) ; } public static keys ( obj ) { const a = new Array < string > ( ) ; let current = obj ; if ( current ) { for ( const k in current ) { a . push ( k ) ; } current = current . __proto ; } while ( current ) { for ( const k in current ) { const val = current [ k ] ; if ( typeof val === 'function' ) { continue ; } a . push ( k ) ; } current = current . __proto ; } return a ; } public static defineProperty ( obj , name , opts ) { if ( opts . get !== null ) { if ( ! obj . __get__ ) { obj . __get__ = { } ; delete obj . __get__ . __index ; } obj . __get__ [ name ] = opts . get ; if ( typeof ( obj . __index ) !== 'function' ) { obj . __index = __get_call_undefined__ ; } } const setMethod = opts . set || ( ( opts . value && typeof ( opts . value ) === 'function' ) ? opts . value : null ) ; if ( setMethod ) { if ( ! obj . __set__ ) { obj . __set__ = { } ; delete obj . __set__ . __newindex ; } obj . __set__ [ name ] = setMethod ; if ( typeof ( obj . __newindex ) !== 'function' ) { obj . __newindex = __set_call_undefined__ ; } } if ( opts . value && typeof ( opts . value ) !== 'function' ) { obj [ name ] = opts . value ; } } public static getOwnPropertyDescriptor ( obj , name ) { const opts = { } ; if ( obj . __get__ ) { const getMethod = obj . __get__ [ name ] ; if ( typeof ( getMethod ) === 'function' ) { opts [ 'get' ] = getMethod ; } } if ( obj . __set__ ) { const setMethod = obj . __set__ [ name ] ; if ( typeof ( setMethod ) === 'function' ) { opts [ 'set' ] = setMethod ; } } const value = obj [ name ] ; if ( value ) { opts [ 'value' ] = value ; } return opts ; } public static getPrototypeOf ( obj ) { return obj . __proto ; } } }