diff --git a/src/api/computed.ts b/src/api/computed.ts index 269cc950e..3bd9210b1 100644 --- a/src/api/computed.ts +++ b/src/api/computed.ts @@ -24,7 +24,7 @@ export const computedDecorator = createPropDecorator( ) => { const { get, set } = descriptor // initialValue is the descriptor for get / set props // Optimization: faster on decorator target or instance? Assuming target - // Optimiziation: find out if declaring on instance isn't just faster. (also makes the property descriptor simpler). But, more memory usage.. + // Optimization: find out if declaring on instance isn't just faster. (also makes the property descriptor simpler). But, more memory usage.. const options = decoratorArgs[0] || {} defineComputedProperty(instance, propertyName, { ...options, get, set }) } diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index dc70cfd51..e01671416 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -1,5 +1,5 @@ import { defineObservableProperty } from "../types/observableobject" -import { fail } from "../utils/utils" +import { fail, invariant } from "../utils/utils" import { IEnhancer } from "../types/modifiers" import { createPropDecorator, BabelDescriptor } from "../utils/decorators2" @@ -18,6 +18,12 @@ export function createDecoratorForEnhancer(enhancer: IEnhancer): IObservabl _decoratorTarget, decoratorArgs: any[] ) => { + if (process.env.NODE_ENV !== "production") { + invariant( + !descriptor || !descriptor.get, + `@observable cannot be used on getter (property "${propertyName}"), use @computed instead.` + ) + } const initialValue = descriptor ? descriptor.initializer ? descriptor.initializer.call(target) : descriptor.value : undefined diff --git a/src/utils/decorators2.ts b/src/utils/decorators2.ts index 4d6325527..e6f163833 100644 --- a/src/utils/decorators2.ts +++ b/src/utils/decorators2.ts @@ -74,7 +74,7 @@ export function createPropDecorator( descriptor: BabelDescriptor | undefined, applyImmediately?: any // This is a special parameter to signal the direct application of a decorator, allow extendObservable to skip the entire type decoration part, - // as the instance to apply the deorator to equals the target + // as the instance to apply the decorator to equals the target ) { if (applyImmediately === true) { propertyCreator(target, prop, descriptor, target, decoratorArguments) diff --git a/test/base/decorate.js b/test/base/decorate.js index f620c55f0..7b7f3f199 100644 --- a/test/base/decorate.js +++ b/test/base/decorate.js @@ -351,3 +351,20 @@ test("decorate should work with ES6 constructor", () => { title: observable }) }) + +test("decorate should not allow @observable on getter", function() { + const obj = { + x: 0, + get y() { + return 0 + } + } + + decorate(obj, { + x: observable, + y: observable + }) + + expect(() => obj.x).toThrow(/"y"/) + expect(() => obj.y).toThrow() +})