diff --git a/src/api/observable.ts b/src/api/observable.ts index a2507f549..dfb5328eb 100644 --- a/src/api/observable.ts +++ b/src/api/observable.ts @@ -68,37 +68,66 @@ export interface IObservableFactory { (value: T): IObservableValue } -export class IObservableFactories { +export interface IObservableFactories { + box(value?: T, name?: string): IObservableValue + shallowBox(value?: T, name?: string): IObservableValue + array(initialValues?: T[], name?: string): IObservableArray + shallowArray(initialValues?: T[], name?: string): IObservableArray + map(initialValues?: IObservableMapInitialValues, name?: string): ObservableMap + shallowMap(initialValues?: IObservableMapInitialValues, name?: string): ObservableMap + object(props: T, name?: string): T & IObservableObject + shallowObject(props: T, name?: string): T & IObservableObject + + /** + * Decorator that creates an observable that only observes the references, but doesn't try to turn the assigned value into an observable.ts. + */ + ref(target: Object, property: string, descriptor?: PropertyDescriptor): any + ref(initialValue: T): T; + + /** + * Decorator that creates an observable converts its value (objects, maps or arrays) into a shallow observable structure + */ + shallow(target: Object, property: string, descriptor?: PropertyDescriptor): any + shallow(initialValues: T[]): IObservableArray + shallow(initialValues: IMap): ObservableMap + shallow(value: T): T + + deep(target: Object, property: string, descriptor?: PropertyDescriptor): any + deep(initialValues: T[]): IObservableArray + deep(initialValues: IMap): ObservableMap + deep(initialValue: T): T + + struct(target: Object, property: string, descriptor?: PropertyDescriptor): any + struct(initialValues: T[]): IObservableArray + struct(initialValues: IMap): ObservableMap + struct(initialValue: T): T +} + +const observableFactories: IObservableFactories = { box(value?: T, name?: string): IObservableValue { if (arguments.length > 2) incorrectlyUsedAsDecorator("box") return new ObservableValue(value, deepEnhancer, name) - } - + }, shallowBox(value?: T, name?: string): IObservableValue { if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowBox") return new ObservableValue(value, referenceEnhancer, name) - } - + }, array(initialValues?: T[], name?: string): IObservableArray { if (arguments.length > 2) incorrectlyUsedAsDecorator("array") return new ObservableArray(initialValues, deepEnhancer, name) as any - } - + }, shallowArray(initialValues?: T[], name?: string): IObservableArray { if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowArray") return new ObservableArray(initialValues, referenceEnhancer, name) as any - } - + }, map(initialValues?: IObservableMapInitialValues, name?: string): ObservableMap { if (arguments.length > 2) incorrectlyUsedAsDecorator("map") return new ObservableMap(initialValues, deepEnhancer, name) - } - + }, shallowMap(initialValues?: IObservableMapInitialValues, name?: string): ObservableMap { if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowMap") return new ObservableMap(initialValues, referenceEnhancer, name) - } - + }, object(props: T, name?: string): T & IObservableObject { if (arguments.length > 2) incorrectlyUsedAsDecorator("object") const res = {} @@ -107,21 +136,14 @@ export class IObservableFactories { // add properties extendObservable(res, props) return res as any - } - + }, shallowObject(props: T, name?: string): T & IObservableObject { if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowObject") const res = {} asObservableObject(res, name) extendShallowObservable(res, props) return res as any - } - - /** - * Decorator that creates an observable that only observes the references, but doesn't try to turn the assigned value into an observable.ts. - */ - ref(target: Object, property: string, descriptor?: PropertyDescriptor): any - ref(initialValue: T): T + }, ref() { if (arguments.length < 2) { // although ref creates actually a modifier descriptor, the type of the resultig properties @@ -130,15 +152,7 @@ export class IObservableFactories { } else { return refDecorator.apply(null, arguments) } - } - - /** - * Decorator that creates an observable converts its value (objects, maps or arrays) into a shallow observable structure - */ - shallow(target: Object, property: string, descriptor?: PropertyDescriptor): any - shallow(initialValues: T[]): IObservableArray - shallow(initialValues: IMap): ObservableMap - shallow(value: T): T + }, shallow() { if (arguments.length < 2) { // although ref creates actually a modifier descriptor, the type of the resultig properties @@ -147,12 +161,7 @@ export class IObservableFactories { } else { return shallowDecorator.apply(null, arguments) } - } - - deep(target: Object, property: string, descriptor?: PropertyDescriptor): any - deep(initialValues: T[]): IObservableArray - deep(initialValues: IMap): ObservableMap - deep(initialValue: T): T + }, deep() { if (arguments.length < 2) { // although ref creates actually a modifier descriptor, the type of the resultig properties @@ -161,12 +170,7 @@ export class IObservableFactories { } else { return deepDecorator.apply(null, arguments) } - } - - struct(target: Object, property: string, descriptor?: PropertyDescriptor): any - struct(initialValues: T[]): IObservableArray - struct(initialValues: IMap): ObservableMap - struct(initialValue: T): T + }, struct() { if (arguments.length < 2) { // although ref creates actually a modifier descriptor, the type of the resultig properties @@ -176,7 +180,7 @@ export class IObservableFactories { return deepStructDecorator.apply(null, arguments) } } -} +} as any export const observable: IObservableFactory & IObservableFactories & { @@ -189,10 +193,7 @@ export const observable: IObservableFactory & } = createObservable as any // weird trick to keep our typings nicely with our funcs, and still extend the observable function -// ES6 class methods aren't enumerable, can't use Object.keys -Object.getOwnPropertyNames(IObservableFactories.prototype) - .filter(name => name !== "constructor") - .forEach(name => (observable[name] = IObservableFactories.prototype[name])) +Object.keys(observableFactories).forEach(name => (observable[name] = observableFactories[name])) observable.deep.struct = observable.struct observable.ref.struct = function() { diff --git a/test/api.js b/test/api.js index 4f2dee9ae..831609ca8 100644 --- a/test/api.js +++ b/test/api.js @@ -8,7 +8,6 @@ test("correct api should be exposed", function(t) { "Atom", "BaseAtom", // TODO: remove somehow "IDerivationState", - "IObservableFactories", "ObservableMap", "Reaction", "action",