﻿/*!
 * Knockout decorator
 * (c) vario
 * License: MIT (http://www.opensource.org/licenses/mit-license.php)
 */

namespace variotry.KnockoutDecorator
{
	var storeObservableKey = "__vtKnockoutObservables__";
	function pushObservable( target: any, propertyKey: string, o: KnockoutObservable<any> | KnockoutComputed<any> )
	{
		if ( !target[storeObservableKey] ) target[storeObservableKey] = [];

		var store = target[storeObservableKey];
		store[propertyKey] = o;
	}

	export function observable( target:any, propertyKey:string ) : void
	{
		var v = target[propertyKey];
		var o = ko.observable( v );
		pushObservable( target, propertyKey, o );
		Object.defineProperty( target, propertyKey, {
			get: o,
			set: o
		});
	}

	export function observableArray( target: any, propertyKey: string ): void
	{
		/*var v = target[propertyKey];
		var o = ko.observableArray();*/
	}

	export function computed(): MethodDecorator
	export function computed( extend: { [key: string]: any }): MethodDecorator;
	export function computed( extend?: { [key: string]: any }): MethodDecorator
	{
		return ( target: any, propertyKey: string, descriptor: PropertyDescriptor ) =>
		{
			var getter = descriptor.get;
			var setter = descriptor.set;

			var c = ko.computed( {
				read: () => getter.call( target ),
				write: setter ? ( v ) => setter.call( target, v ) : null
			});

			if ( extend )
			{
				c.extend( extend );
			}

			pushObservable( target, propertyKey, c );

			descriptor.get = c;
			if ( setter )
			{
				descriptor.set = c;
			}
		}
	}
}

﻿/*!
 * Knockout decorator
 * (c) vario
 * License: MIT (http://www.opensource.org/licenses/mit-license.php)
 */

namespace variotry.KnockoutDecorator
{
	var storeObservableKey = "__vtKnockoutObservables__";
	export function observable( target:any, propertyKey:string )
	{
		var v = target[propertyKey];
		var o = ko.observable( v );
		Object.defineProperty( target, propertyKey, {
			get: () => o(),
			set: ( v ) => o( v )
		});
		var d = Object.getOwnPropertyDescriptor( target, propertyKey );
	}
	export function observableArray()
	{
	}
	export function computed()
	{
	}
}

--- 
+++ 
@@ -7,20 +7,57 @@
 namespace variotry.KnockoutDecorator
 {
 	var storeObservableKey = "__vtKnockoutObservables__";
-	export function observable( target:any, propertyKey:string )
+	function pushObservable( target: any, propertyKey: string, o: KnockoutObservable<any> | KnockoutComputed<any> )
+	{
+		if ( !target[storeObservableKey] ) target[storeObservableKey] = [];
+
+		var store = target[storeObservableKey];
+		store[propertyKey] = o;
+	}
+
+	export function observable( target:any, propertyKey:string ) : void
 	{
 		var v = target[propertyKey];
 		var o = ko.observable( v );
+		pushObservable( target, propertyKey, o );
 		Object.defineProperty( target, propertyKey, {
-			get: () => o(),
-			set: ( v ) => o( v )
+			get: o,
+			set: o
 		});
-		var d = Object.getOwnPropertyDescriptor( target, propertyKey );
 	}
-	export function observableArray()
+
+	export function observableArray( target: any, propertyKey: string ): void
 	{
+		/*var v = target[propertyKey];
+		var o = ko.observableArray();*/
 	}
-	export function computed()
+
+	export function computed(): MethodDecorator
+	export function computed( extend: { [key: string]: any }): MethodDecorator;
+	export function computed( extend?: { [key: string]: any }): MethodDecorator
 	{
+		return ( target: any, propertyKey: string, descriptor: PropertyDescriptor ) =>
+		{
+			var getter = descriptor.get;
+			var setter = descriptor.set;
+
+			var c = ko.computed( {
+				read: () => getter.call( target ),
+				write: setter ? ( v ) => setter.call( target, v ) : null
+			});
+
+			if ( extend )
+			{
+				c.extend( extend );
+			}
+
+			pushObservable( target, propertyKey, c );
+
+			descriptor.get = c;
+			if ( setter )
+			{
+				descriptor.set = c;
+			}
+		}
 	}
 }
Implement computed decorator.
Improved observable decorator.
