Search code examples
javascripttypescriptmobx

Is there a simpler way to exclude fields from mobx makeAutoObservable in TypeScript?


I am migrating a view model class from plain javaScript to typeScript.

In javaScript I could call makeAutoObservable and AFTER that define additional fields that need to be non-observable, and that worked just fine:

class List {

    constructor(notifier, apiClient) {
        makeAutoObservable(this)

        // Things below will not become observable

        this.notifier = notifier
        this.apiClient = apiClient
        this.loadOperation = LoadOperation(this.executeLoad, { onError: this.loadFailed })
        this.textFilter = TextFilter()
        this.showInactiveFilter = ShowInactiveFilter()
        this.sorter = Sorter()
        this.pager = Pager()
        this.orchestrator = Orchestrator({
            loadOperation: this.loadOperation,
            filters: [this.textFilter, this.showInactiveFilter],
            sorter: this.sorter,
            pager: this.pager
        })
        this.navigator = Navigator()
        this.lifecycle = Lifecycle(this.loadOperation.execute)
    }
 
    // Other stuff that becomes observable

}

But now, in the typeScript I am forced to forward declare fields before initializing them, so the makeAutoObservable already sees them when called and as a result I need to exclude them one by one:

class List {

    readonly notifier
    readonly apiClient
    readonly loadOperation
    readonly textFilter
    readonly showInactiveFilter
    readonly sorter
    readonly pager
    readonly orchestrator
    readonly navigator
    readonly lifecycle

    constructor(notifier: Notifier, apiClient: any) {
        makeAutoObservable(this, {
            notifier: false,
            apiClient: false,
            navigator: false,
            loadOperation: false,
            textFilter: false,
            showInactiveFilter: false,
            sorter: false,
            pager: false,
            orchestrator: false,
            lifecycle: false
        })

        this.notifier = notifier
        this.apiClient = apiClient
        this.loadOperation = LoadOperation(this.executeLoad, { onError: this.loadFailed })
        this.textFilter = TextFilter()
        this.showInactiveFilter = ShowInactiveFilter()
        this.sorter = Sorter()
        this.pager = Pager()
        this.orchestrator = Orchestrator({
            loadOperation: this.loadOperation,
            filters: [this.textFilter, this.showInactiveFilter],
            sorter: this.sorter,
            pager: this.pager
        })
        this.navigator = Navigator()
        this.lifecycle = Lifecycle(this.loadOperation.execute)
    }

    // Other stuff that becomes observable
}

Is there a way I could use this.field = ... in typeScript constructor without forward declaration (just like I did in javaScript)?

Is there any simpler way (other than one by one) to exclude those fields from observation?


Solution

  • Use their makeObservable-method instead, so instead of excluding everything you dont want, you include the things you actually want.

    So lets say you want notifier to be an observable and not the rest:

    makeObservable(this, {
        notifier: observable
    })