Skip to content

Commit

Permalink
Merge pull request #1450 from makepost/master
Browse files Browse the repository at this point in the history
Decorate: Fix in type-checked JS
  • Loading branch information
mweststrate authored Mar 27, 2018
2 parents e2cc3b3 + c71ee1d commit 8562e77
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/api/decorate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { invariant, isPlainObject } from "../utils/utils"

export function decorate<T>(
clazz: new (...args: any[]) => T,
decorators: { [P in keyof T]: MethodDecorator | PropertyDecorator }
decorators: { [P in keyof T]?: MethodDecorator | PropertyDecorator }
): void
export function decorate<T>(
object: T,
decorators: { [P in keyof T]: MethodDecorator | PropertyDecorator }
decorators: { [P in keyof T]?: MethodDecorator | PropertyDecorator }
): T
export function decorate(thing: any, decorators: any) {
process.env.NODE_ENV !== "production" &&
Expand Down
2 changes: 1 addition & 1 deletion src/api/observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function createObservable(v: any, arg2?: any, arg3?: any) {
export interface IObservableFactory {
// observable overloads
(value: number | string | null | undefined | boolean): never // Nope, not supported, use box
(target: Object, key: string, baseDescriptor?: PropertyDescriptor): any // decorator
(target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor): any // decorator
<T = any>(value: T[], options?: CreateObservableOptions): IObservableArray<T>
<K = any, V = any>(value: Map<K, V>, options?: CreateObservableOptions): ObservableMap<K, V>
<T extends Object>(
Expand Down
43 changes: 38 additions & 5 deletions test/base/decorate.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @ts-check

import {
observable,
computed,
Expand All @@ -17,6 +19,7 @@ import {

test("decorate should work", function() {
class Box {
// @ts-ignore
uninitialized
height = 20
sizes = [2]
Expand All @@ -33,7 +36,9 @@ test("decorate should work", function() {
)
}
addSize() {
// @ts-ignore
this.sizes.push([3])
// @ts-ignore
this.sizes.push([4])
}
constructor() {
Expand Down Expand Up @@ -105,7 +110,9 @@ test("decorate should work with plain object", function() {
)
},
addSize() {
// @ts-ignore
this.sizes.push([3])
// @ts-ignore
this.sizes.push([4])
}
}
Expand Down Expand Up @@ -171,7 +178,9 @@ test("decorate should work with Object.create", function() {
)
},
addSize() {
// @ts-ignore
this.sizes.push([3])
// @ts-ignore
this.sizes.push([4])
}
}
Expand Down Expand Up @@ -233,12 +242,16 @@ test("decorate should work with constructor function", function() {
configurable: true,
enumerable: false,
get() {
/** @type {Box} */
var t /** @type {any} */ = this

return (
this.undeclared *
this.height *
this.sizes.length *
this.someFunc() *
(this.uninitialized ? 2 : 1)
// @ts-ignore
t.undeclared *
t.height *
t.sizes.length *
t.someFunc() *
(t.uninitialized ? 2 : 1)
)
}
})
Expand All @@ -262,6 +275,7 @@ test("decorate should work with constructor function", function() {
}

const box = new Box()
// @ts-ignore
box.undeclared = 1

expect(isObservableObject(box)).toBe(true)
Expand All @@ -278,6 +292,7 @@ test("decorate should work with constructor function", function() {
var ar = []

autorun(() => {
// @ts-ignore
ar.push(box.width)
})

Expand All @@ -292,11 +307,14 @@ test("decorate should work with constructor function", function() {
expect(ar.slice()).toEqual([40, 20, 60, 210, 420])
box.addSize()
expect(ar.slice()).toEqual([40, 20, 60, 210, 420, 700])
// @ts-ignore
box.undeclared = 2
expect(ar.slice()).toEqual([40, 20, 60, 210, 420, 700, 1400])

const box2 = new Box()
// @ts-ignore
box2.undeclared = 1
// @ts-ignore
expect(box2.width).toBe(40) // no shared state!
})

Expand All @@ -318,3 +336,18 @@ test("decorate should work with inheritance through Object.create", () => {
expect(child2.x).toBe(5)
expect(child1.x).toBe(4)
})

test("decorate should work with ES6 constructor", () => {
class Todo {
constructor() {
this.finished = false
this.id = Math.random()
this.title = ""
}
}

decorate(Todo, {
finished: observable,
title: observable
})
})

0 comments on commit 8562e77

Please sign in to comment.