export function observable(keyOrTargetOrConfig: any, _key?: string, _descriptor?: PropertyDescriptor) {
  let deco = function(target, key, descriptor) {
    if (!key) {
      key = typeof keyOrTargetOrConfig === 'string' ? keyOrTargetOrConfig : keyOrTargetOrConfig.name;
    }
    // use a convention to compute the inner property name and the callback
    // function name.
    let innerPropertyName = `_${key}`;
    let callbackName = (keyOrTargetOrConfig && keyOrTargetOrConfig.changeHandler) || `${key}Changed`;

    if (descriptor) {
      // babel passes in the property descriptor with a method to get the initial value.

      // set the initial value of the property if it is defined.
      if (typeof descriptor.initializer === 'function') {
        target[innerPropertyName] = descriptor.initializer();
      }
    } else {
      descriptor = {};
      target = target.prototype;
    }

    // we're adding a getter and setter which means the property descriptor
    // cannot have a "value" or "writable" attribute
    delete descriptor.writable;
    delete descriptor.initializer;

    // add the getter and setter to the property descriptor.
    descriptor.get = function() { return this[innerPropertyName]; };
    descriptor.set = function(newValue) {
      let oldValue = this[innerPropertyName];
      this[innerPropertyName] = newValue;
      if (this[callbackName]) {
        this[callbackName](newValue, oldValue);
      }
    };

    // make sure Aurelia doesn't use dirty-checking by declaring the property's
    // dependencies. This is the equivalent of "@computedFrom(...)".
    descriptor.get.dependencies = [innerPropertyName];

    Reflect.defineProperty(target, key, descriptor);
  };

  if (_key) {
    return deco(keyOrTargetOrConfig, _key, _descriptor);
  }

  return deco;
}

@@ -20,22 +20,17 @@
 ervable(
-keyOrT
+t
 argetOrC
@@ -45,13 +45,11 @@
 ny, 
-_
 key
-?
 : st
@@ -54,17 +54,16 @@
 string, 
-_
 descript
@@ -94,19 +94,8 @@
  %7B%0A 
- let deco =
  fun
@@ -99,16 +99,21 @@
 function
+ deco
 (target,
@@ -124,27 +124,92 @@
 , descriptor
-) %7B
+, config) %7B // eslint-disable-line no-shadow%0A    // class decorator?
 %0A    if (!ke
@@ -209,106 +209,113 @@
 if (
-!
 key
-) %7B%0A      key = typeof keyOrTargetOrConfig === 'string' ? keyOrTargetOrConfig : keyOrTargetOrC
+ === undefined) %7B%0A      target = target.prototype;%0A      key = typeof config === 'string' ? config : c
 onfi
@@ -324,24 +324,25 @@
 name;%0A    %7D%0A
+%0A
     // use a
@@ -391,47 +391,8 @@
 name
- and the callback%0A    // function name.
 %0A   
@@ -431,69 +431,108 @@
 %7D%60;%0A
+%0A
     
-let callbackName = (keyOrTargetOrConfig && keyOrTargetOrC
+// determine callback name based on config or convention.%0A    const callbackName = (config && c
 onfi
@@ -914,41 +914,8 @@
 %7B%7D;%0A
-      target = target.prototype;%0A
     
@@ -1735,17 +1735,16 @@
 %0A  %7D
-;
 %0A%0A  if (
 _key
@@ -1743,38 +1743,120 @@
 if (
-_
 key
-) %7B%0A    return deco(keyOrT
+ === undefined) %7B%0A    // parens...%0A    return (t, k, d) =%3E deco(t, k, d, targetOrConfig);%0A  %7D%0A  return deco(t
 arge
@@ -1870,15 +1870,13 @@
 ig, 
-_
 key, 
-_
 desc
@@ -1888,26 +1888,477 @@
 r);%0A
-  
 %7D%0A%0A
-  return deco;%0A%7D
+/*%0A          %7C typescript       %7C babel%0A----------%7C------------------%7C-------------------------%0Aproperty  %7C config           %7C config%0Aw/parens  %7C target, key      %7C target, key, descriptor%0A----------%7C------------------%7C-------------------------%0Aproperty  %7C target, key      %7C target, key, descriptor%0Ano parens %7C n/a              %7C n/a%0A----------%7C------------------%7C-------------------------%0Aclass     %7C config           %7C config%0A          %7C target           %7C target%0A*/
 %0A

fix TypeScript support