Skip to content

v8 TS types don't allow passing a component prop named context #1957

Closed
@markerikson

Description

@markerikson

Original discussion in #1187 starting at #1187 (comment) , posted by @strongui .

Pasting some relevant comment extracts:

we have a huge app, we haven't had time to update until recently.

const connector = connect(mapStateToProps, mapDispatchToProps);

const connectorCore = connect(null, mapDispatchToPropsCoreMethods);

const BaseComp = (props) => {
  return <div></div>
}

// This COMP will get all it's data from the redux store
export const FullComponent = connector(BaseComp);
// This COMP will demand data from the parent
export const NonDataComponent = connectorCore(BaseComp);

Basically this. Same component, but one gets data form redux, the other will get data from parent.

Sandbox: https://codesandbox.io/s/tender-mestorf-x272kj?file=/src/index.tsx

now you see the TS error:

Type '"LIST"' is not assignable to type '("LIST" | "CARD") & Context<ReactReduxContextValue<any, AnyAction>>'.ts(2322)

From me:

Hmm. Interesting. If I fix the use of connector(Button), and then swap back to React-Redux v7, the wrapped Button component says that context is just that enum, not a ReactReduxContext instance.

I wonder what about our types changed there? It most likely had something to do with the TS conversion process.

The internal logic for "what do we do with props.context internally once we see it" hasn't changed, and if I'm reading this right, it ought to actually pass that through properly if it's not a context instance:

      const ContextToUse: ReactReduxContextInstance = useMemo(() => {
        // Users may optionally pass in a custom context instance to use instead of our ReactReduxContext.
        // Memoize the check that determines which context instance we should use.
        return propsContext &&
          propsContext.Consumer &&
          // @ts-ignore
          isContextConsumer(<propsContext.Consumer />)
          ? propsContext
          : Context
      }, [propsContext, Context])

      // Retrieve the store and ancestor subscription via context, if available
      const contextValue = useContext(ContextToUse)

It's probably this part:

export interface ConnectProps {
  /** A custom Context instance that the component can use to access the store from an alternate Provider using that same Context instance */
  context?: ReactReduxContextInstance
  /** A Redux store instance to be used for subscriptions instead of the store from a Provider */
  store?: Store
}

interface InternalConnectProps extends ConnectProps {
  reactReduxForwardedRef?: React.ForwardedRef<unknown>
}

    function ConnectFunction<TOwnProps>(
      props: InternalConnectProps & TOwnProps
    )  {
       // omit
    }

Given that, I think this would run, but it won't compile, which is an issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions