John Reilly
John Reilly

Reputation: 6269

mobx-state-tree - can types.model be used to model generic types?

I'm using mobx-state-tree for the first time and I'm trying to use types.model to model a generic type. I'm trying to take this existing mobx code:

/**
 * Models an Async request / response - all the properties exposed are
 * decorated with `observable.ref`; i.e. they are immutable
 */
class Async<TRequest, TResponse> implements IAsyncProps<TResponse> {
    /**
     * Whether a request is in process
     */
    @observable.ref isRequesting: boolean = false;

    /**
     * (optional) The response received last time a request was run
     */
    @observable.ref response?: TResponse;

    /**
     * (optional) The error received last time a request was run
     */
    @observable.ref error?: string;

    constructor(private process: (request: TRequest) => Promise<TResponse>) {

    }

    @action
    async run(request?: TRequest) {
        try {
            this.isRequesting = true;
            this.response = undefined;
            this.error = undefined;

            const response = await this.process(request);
            this.runSuccess(response);
        } catch (error) {
            this.runError(error);
        }
    }

    @action private runSuccess(response: TResponse) {
        this.response = response;
        this.isRequesting = false;
    }

    @action private runError(error: any) {
        this.error = error.message ? error.message : error;
        this.isRequesting = false;
    }

    @action
    reset() {
        this.isRequesting = false;
        this.response = undefined;
        this.error = undefined;
        return this;
    }
}

And I want to port it across to a types.model. I've got this far:

const Async2 = types.model('Async2', {
    isRequesting: types.boolean,
    response: types.optional(/*types.? what goes here ???*/, undefined),
    error: types.optional(types.string, undefined)
});

But I'm stuck on how I can generically type the response. I can handle the rest of the actions - does anyone know if that's possible?

Upvotes: 2

Views: 967

Answers (1)

Mattia Manzo Manzati
Mattia Manzo Manzati

Reputation: 586

If you think about generics they are dynamically generated classes. So you can just write a function that given the two generics type return your model definition using them :)

Something like

Function Async(ReqType, ResType){ . Return t.model({ . Req: ReqType, . Res: ResType . }) }

I also recommend you to memoize that function, so if you call it again it will be given back the same model type without creating a new one! :)

Upvotes: 1

Related Questions