Skip to content

Commit 4d56bf6

Browse files
StephenHaneymweststrate
authored andcommitted
Observable decorator on computed symbol keys (#2175)
* Decorator checks for typeof symbol now too, plus tests... failing with callstack exceeded * Updating comments * Fixing comments * Removing accidental semicolon * Add propertyCreator to symbol key properties too * Updating changelog
1 parent e5a2170 commit 4d56bf6

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
- Fix running mobx in web worker [#2184](https://github.com/mobxjs/mobx/pull/2184/files)
33
- Fixed flow typings for Facebook's Flow. A new `CancellablePromise` Flow type is exported.
44

5+
- Added support for symbol keys on observable properties.
6+
57
# 5.14.2
68

79
- Fixed installation issue trying to run `postinstall` hook for a website [#2165](https://github.com/mobxjs/mobx/issues/2165).

src/api/observable.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function getEnhancerFromOptions(options: CreateObservableOptions): IEnhancer<any
7979
*/
8080
function createObservable(v: any, arg2?: any, arg3?: any) {
8181
// @observable someProp;
82-
if (typeof arguments[1] === "string") {
82+
if (typeof arguments[1] === "string" || typeof arguments[1] === "symbol") {
8383
return deepDecorator.apply(null, arguments as any)
8484
}
8585

src/utils/decorators.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ export function initializeInstance(target: DecoratorTarget) {
5757
const decorators = target[mobxPendingDecorators]
5858
if (decorators) {
5959
addHiddenProp(target, mobxDidRunLazyInitializersSymbol, true)
60-
for (let key in decorators) {
61-
const d = decorators[key]
60+
// Build property key array from both strings and symbols
61+
const keys = [...Object.getOwnPropertySymbols(decorators), ...Object.keys(decorators)]
62+
for (const key of keys) {
63+
const d = decorators[key as any]
6264
d.propertyCreator(target, d.prop, d.descriptor, d.decoratorTarget, d.decoratorArguments)
6365
}
6466
}
@@ -113,7 +115,8 @@ export function createPropDecorator(
113115

114116
export function quacksLikeADecorator(args: IArguments): boolean {
115117
return (
116-
((args.length === 2 || args.length === 3) && typeof args[1] === "string") ||
118+
((args.length === 2 || args.length === 3) &&
119+
(typeof args[1] === "string" || typeof args[1] === "symbol")) ||
117120
(args.length === 4 && args[3] === true)
118121
)
119122
}

test/base/typescript-tests.ts

+28
Original file line numberDiff line numberDiff line change
@@ -1647,3 +1647,31 @@ test("verify #1528", () => {
16471647

16481648
expect(appState.timer).toBe(0)
16491649
})
1650+
1651+
test("#2159 - computed property keys", () => {
1652+
const testSymbol = Symbol("test symbol")
1653+
const testString = "testString"
1654+
1655+
class TestClass {
1656+
@observable [testSymbol] = "original symbol value";
1657+
@observable [testString] = "original string value"
1658+
}
1659+
1660+
const o = new TestClass()
1661+
1662+
const events: any[] = []
1663+
observe(o, testSymbol, ev => events.push(ev.newValue, ev.oldValue))
1664+
observe(o, testString, ev => events.push(ev.newValue, ev.oldValue))
1665+
1666+
runInAction(() => {
1667+
o[testSymbol] = "new symbol value"
1668+
o[testString] = "new string value"
1669+
})
1670+
1671+
t.deepEqual(events, [
1672+
"new symbol value", // new symbol
1673+
"original symbol value", // original symbol
1674+
"new string value", // new string
1675+
"original string value" // original string
1676+
])
1677+
})

0 commit comments

Comments
 (0)