类型“DefaultRootState”上不存在属性“user”

Tai*_*iga 2 typescript redux

情况

  • 我正面临这个错误'user' does not exist on type 'DefaultRootState'.我试图解决它,但我没有想出解决方案。

这是我的回购

错误

C:/Users/taiga/Github/Typescript/typescript-admin/admin/src/secure/components/Nav.tsx
TypeScript error in C:/Users/taiga/Github/Typescript/typescript-admin/admin/src/secure/components/Nav.tsx(44,50):
Property 'user' does not exist on type 'DefaultRootState'.  TS2339
Run Code Online (Sandbox Code Playgroud)

导航.tsx

class Nav extends Component<{ user: User }> {
  state = {
    redirect: false
  };

  handleClick = async () => {
    await axios.post('logout', {});

    this.setState({
      redirect: true
    });
  };

  render() {
    if (this.state.redirect) {
      return <Redirect to={'/login'} />;
    }

    return (
      <nav className="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
        <ul className="my-2 my-md-0 mr-md-3">
          <Link to={'/profile'} className="p-2 text-white">
            {this.props.user.name}
          </Link>
        </ul>
      </nav>
    );
  }
}

export default connect((state) => ({ user: state.user }))(Nav);
Run Code Online (Sandbox Code Playgroud)

用户.ts

mport { Role } from './role';

export class User {
  id: number;
  first_name: string;
  last_name: string;
  email: string;
  role: Role;
  permissions: string[];

  constructor(
    id = 0,
    first_name = '',
    last_name = '',
    email = '',
    role = new Role(),
    permissions: string[] = []
  ) {
    this.id = id;
    this.first_name = first_name;
    this.last_name = last_name;
    this.email = email;
    this.role = role;
    this.permissions = permissions;
  }
Run Code Online (Sandbox Code Playgroud)

setUserReducer.ts

import { User } from '../../classes/user';

const setUserReducer = (
  state = { user: new User() },
  action: { type: string; user: User }
) => {
  switch (action.type) {
    case 'SET_USER':
      return {
        ...state,
        user: action.user
      };
    default:
      return state;
  }
};

export default setUserReducer;
Run Code Online (Sandbox Code Playgroud)

Lin*_*ste 6

问题是connectHOC 不知道state类型是您特定应用程序的状态类型,而不仅仅是任何状态类型。当它不知道您的特定状态的类型时,它假定状态是 type DefaultRootState,它在 react-redux types 包中定义为空对象{}

有多种方法可以解决这个问题。根据 types 包的建议,一种可能性是覆盖的定义DefaultRootState并将其替换为应用程序的实际状态接口。

当使用 react-redux 时,用户可以扩充此接口以添加根状态的默认类型。使用模块扩充将您自己的类型定义附加到 your_custom_type.d.ts 文件中。https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation

另一种更容易实现的可能性是在mapStateToProps函数中声明预期的状态类型。

export default connect((state: {user: User}) => ({ user: state.user }))(Nav);
Run Code Online (Sandbox Code Playgroud)

现在打字稿知道你state有一个user类型为的属性User

您还可以connect在调用函数时在该函数上设置通用参数,但我建议使用以前的方法。

export default connect<{user: User}, {}, {}, {user: User}>((state) => ({ user: state.user }))(Nav);
Run Code Online (Sandbox Code Playgroud)