Mobx Generic Observer using Typescript typing

2.9k Views Asked by At

I would like to wrap the following function in mobx's observer(), but can't seem to figure out how to do that (or if it's possible) while maintaining the generic typing:

interface GenericProps<T> {
  arg: T;
}
const foo: <T>(props: GenericProps<T>) => T = (props) => props.arg;

This is a global exported function, so using the @observer decorator is not an option (I think), I need to use the observer() function from mobx-lite-react.

What I want is something like

interface GenericProps<T> {
  arg: T;
}
const foo = observer<T>((props: GenericProps<T>) => props.arg);

Probably related to https://github.com/mobxjs/mobx-react-lite/issues/243, but from the conversation it is not clear to me how I would go about implementing the generic observer in my case.

2

There are 2 best solutions below

1
On BEST ANSWER
  1. your sample is not react component, you need to match React.FunctionComponent interface
const foo_1: <T>(props: GenericProps<T>) => React.ReactElement | null = (props) => <>{JSON.stringify(props.arg)}</>;
  1. add observer (this should work already thanks improvements in TS 3.4 or 3.5)
const foo_2: <T>(props: GenericProps<T>) => React.ReactElement | null = observer((props) => <>{JSON.stringify(props.arg)}</>);
  1. if on older TS you need to move type declaration to the function itself (note the extends unknown which tells compiler this is generic definition and not JSX tag, return type doesn't need to be specified since it will be inferred)
const foo_3 = observer(<T extends unknown>(props: GenericProps<T>) => <>{JSON.stringify(props.arg)}</>);
2
On

Is that what you want?

interface GenericProps<T> {
  arg: T
}

const foo = <T extends IReactComponent>(props: GenericProps<T>) => observer(props.arg)

I am not quite understand because in the first example you have function which returns another function, but in the second example you just pass function to observer but it is not possible since observer only accepts something that extends IReactComponent