4

I am kind of new with using Typescript in React. I tried to connect my Redux with my container component, but for some reason it keeps giving me type errors. I have gone through many stack overflow posts but still cannot understand what is happening.

My redux tpes file:

export interface StoreState {
    languageName: string,
    enthusiasmLevel: number
}

My container component file:

// React imports
import React from 'react';
import {Link } from 'react-router-dom';
import * as actions from '../../redux/actions/actions';
import { StoreState } from '../../redux/types/types';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';

interface NavbarComponentProps {
  name: string;
  enthusiasmLevel?: number;
  onIcrement?: () => void;
  onDecrement?: () => void;
}

interface DispatchFromProps {
  onDecrement: () => void,
  onIncrement: () => void
}
interface StateFromProps {
  name: string,
  enthusiasmLevel: number
}

type Props = StateFromProps & DispatchFromProps & NavbarComponentProps;

class NavbarContainer extends React.Component<Props, {}> {

  public static defaultProps = {
    enthusiamsLevel: 1
  }

  public render() {
    return (
      <div className='App'>
        navbar works.

        <Link to='/'>left nav</Link>

{/*         
       <p>Hello {name + getExclamationMarks(this.props.enthusiasmLevel)} </p> */}

      <button onClick={this.props.onDecrement}> - </button>
      <button onClick={this.props.onIcrement}> + </button>
      </div>

    );
  }
}

function mapStateToProps({ enthusiasmLevel, languageName}: StoreState) {
  return {
    enthusiasmLevel,
    name: languageName
  }
}

function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiamsAction>) {
  return {
    onDecrement: () => dispatch(actions.decrementEnthusiasm()),
    onIncrement: () => dispatch(actions.incrementEnthusiasm())
  }
}

export default connect<StateFromProps, DispatchFromProps, NavbarComponentProps, StoreState>(mapStateToProps, mapDispatchToProps)(NavbarContainer);

My error: enter image description here

I am guessing that there is a problem with resetting the languageName to name, however even changing that didn't help.

Any help would be much appreciated. Cheers!

1 Answer 1

3

The relevant signature is the following

<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = {}>(
    mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
    mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>
)

When omitting the last State it defaults to {}.

You should be calling connect<StateFromProps, DispatchFromProps, NavbarContainerProps, StoreState>(...)(...). Think connect<ReduxInjected, DispatchInjected, GivenByParentWhenUsingThisComponent, ReduxStoreType>.

Notice I changed the interface a bit, your Props should be NavbarContainerProps and only include the props that are passed in manually (not from the store).

Then I like to write a type alias type Props = StateFromProps & DispatchFromProps & NavbarContainerProps; which you use for defining the component.

class NavbarContainer extends React.Component<Props, {}> {
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply. I updated the signature to mix all the props together. Thank you for that it's a nice trick type Props = StateFromProps & DispatchFromProps & NavbarComponentProps; class NavbarContainer extends React.Component<Props, {}> {} I am afraid I do not really get the issue with the connect. I changed my code a little, but I am still unsure about how to put in the parameters after the signature definition. export default connect<StateFromProps, DispatchFromProps, NavbarComponentProps, StoreState>(mapStateToProps, mapDispatchToProps)(NavbarContainer);
When the 4th generic type parameter was omitted (StoreState) it defaulted to an empty object. mapStateToProps is a function from StoreState to StateFromProps but because that 4th parameter was missing, it was trying to type check as a function from {} to StateFromProps which is where that error came from.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.