Reputation: 6269
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
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