-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
65 lines (54 loc) · 1.94 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// https://github.com/mobxjs/mobx/discussions/2850#discussioncomment-497321
import {
$mobx,
AnnotationsMap,
CreateObservableOptions,
isObservable,
makeObservable
} from 'mobx'
const annotationsSymbol = Symbol()
const objectPrototype = Object.prototype
type NoInfer<T> = [T][T extends any ? 0 : never];
type Annotations<T extends Object = Object, U extends PropertyKey = never> = AnnotationsMap<T, U>;
const makeAutoObservable = <
T extends object & { [annotationsSymbol]?: any },
AdditionalKeys extends PropertyKey = never
>(
target: T,
overrides?: Annotations<T, NoInfer<AdditionalKeys>>,
options?: CreateObservableOptions
): T => {
// Make sure nobody called makeObservable/makeAutoObservable/extendObservable/makeSimpleAutoObservable previously (eg in parent constructor)
if (isObservable(target)) {
throw new Error('Target must not be observable')
}
let annotations = target[annotationsSymbol]
if (!annotations) {
annotations = {} as Annotations
let current = target
while (current && current !== objectPrototype) {
Reflect.ownKeys(current).forEach(key => {
if (key === $mobx || key === 'constructor') return
annotations![key] = !overrides ? true : key in overrides ? overrides[key as keyof typeof overrides] : true
})
current = Object.getPrototypeOf(current)
}
// Cache if class
const proto = Object.getPrototypeOf(target)
if (proto && proto !== objectPrototype) {
Object.defineProperty(proto, annotationsSymbol, {value: annotations})
}
} else {
// Apply only annotations existed in target already
// https://github.com/mobxjs/mobx/discussions/2850#discussioncomment-1396837
const tmp = {} as Annotations<Object, any>
for (const key in target) {
if (annotations[key]) {
tmp[key] = annotations[key]
}
}
annotations = tmp
}
return makeObservable(target, annotations, options)
}
export default makeAutoObservable