Repository: mobxjs/mobx-react

Issue #256: [Question] How to get typesafe injection 
Created: 2017-05-17T06:51:27Z
I've looked at
https://github.com/mobxjs/mobx-react#strongly-typing-inject
but am not sure if there is a better way. I generally pick out a lot of things to inject. Imagine
@inject((stores) => {
  return {
    storeA: stores.storeA,
    storeB: stores.storeB,
    storeC: stores.storeC,
    somethingOnStoreD: stores.storeD.something
})
MyComponent extends React.Component<IMyComponentProps>

But if I render this component from a parent component, then I can't render it without marking each one of the stores or props as optional in IMyComponentProps or pass in values for each of those props. This is documented but makes it very difficult to actually use the props in the component.
Basically anytime I use something from storeA, storeB, or somethingOnStoreD - I first have to check for the presence of those or else typescript will complain that it is potentially undefined.
I think part of the problem is typescript currently doesn't allow class mutations from decorators. But even when I use inject as a function, the tsd file specifies inject returns the original target which expects the props declared in IMyComponentProps
export function inject<T, P>(storesToProps : IStoresToProps<T, P>): (<TFunction extends IReactComponent<T | P>>(target: TFunction) => (TFunction & IWrappedComponent<T>)); // decorator
If I were to change it the tsd to
export function inject<T, P>(storesToProps : IStoresToProps<T, P>): (<TFunction extends IReactComponent<T | P>>(target: TFunction) => (IReactComponent<P> & IWrappedComponent<T>)); // decorator
and inject with
interface IPropsFromStore {
  storeA: storeA;
  storeB: storeB;
  ...
}
IPropsFromParent {
}
inject<IPropsFromStore, IPropsFromParent>((stores) => {
  return {
    storeA: stores.storeA,
    storeB: stores.storeB,
    storeC: stores.storeC,
    somethingOnStoreD: stores.storeD.something
})(
MyComponent extends React.Component<IPropsFromStore & IPropsFromParent>)

This allows me to use the function to return a component that no longer requires all the props that will be inserted with injection. It also will validate that the inject function is returning the props that I am expecting and also allows MyComponent to use props from injection directly and force checks on props from parent. The problem is this declaration will no longer allow inject to be used as a decorator since its no longer clear that inject returns a signature compatible with the original constructor. I kind of wish this functionality somehow existed because I could be willing to forego decorators to have a better type-checking experience but not sure if its possible.
Sorry this was a bit long, do you know of a better way to solve these problems?
Thanks!

Duplicate issue #323: Typings on inject
Created: 2017-09-11T08:21:26Z
Hi, the typings on inject are a bit off.
I have Component with props { foo: string };
Then I will perform mapping:
type ContainerProps = {
  bar: number
}
type ComponentProps = {
  foo: string
}

const Composed = inject<ComponentProps, ContainerProps>((stores, props) => 
    ({ foo: stores.some[props.bar]}))(Component);
The problem is that the returning component has props of type ComponentProps. so, when I try to use this component:
<Composed bar={4}  />
I get error that foo parameter is missing. That's obviously incorrect, as the composed component should only receive bar.

Closing comment (2017-09-18T11:58:01Z): I think this is a duplicate of #256 ?