将connect-redux-shorthand表示法转换为JS / TypeScript

时间:2018-09-10 12:41:35

标签: javascript typescript react-redux

在搜索和阅读的同时,我仍然是新手(或更准确地说,是一个生锈的兼职JS开发人员),我的问题可能非常简单。

我正在尝试将现有的JS项目转换为TypeScript。我很努力地理解connect-redux-decorator,JS速记符号和箭头命名法在一行中的组合:

@connect(({session: { loggedIn }}) => ({loggedIn}), {establishConnection})

如果有人可以将其转换为“导出默认连接”方法或只是函数/类表示法,我将不胜感激。

在以下代码中,该行导致此TypeScript错误消息:

[ts]
Unable to resolve signature of class decorator when called as an expression.
Type 'ComponentClass<Pick<{}, never>, any> & { WrappedComponent: ComponentType<{}>; }' is 
not assignable to type 'typeof AuthenticatedApp'.
Type 'Component<Pick<{}, never>, any, any>' is not assignable to type 'AuthenticatedApp'.
Property 'componentDidMount' is optional in type 
'Component<Pick<{}, never>, any, any>' but required in type 'AuthenticatedApp'.`

代码:

import * as React from 'react';
import { connect } from 'react-redux'
import Connecting from '../components/Connecting'
import { establishConnection } from '../actions/login'

@connect(({session: { loggedIn }}) => ({loggedIn}), {establishConnection})
export default class AuthenticatedApp extends React.Component {
  componentDidMount() {
    this.props.establishConnection()
  }

  componentWillReceiveProps(nextProps) {
    if(!nextProps.loggedIn) {
      this.props.establishConnection()
    }
  }

  render() {
    const { loggedIn, children } = this.props
    const appContent = loggedIn ? children : <Connecting />

    return (
      <div>
        {appContent}
      </div>
    )
  }
}

虽然错误消息本身的解决方式也可能完全不同,但我想用“普通”代码替换装饰器,希望它能解决问题。

我的尝试看起来像这样(完全错误,我知道):

function mapStateToProps(loggedIn) {
   return {loggedIn} = session: { loggedIn };
}
...
class AuthenticatedApp extends React.Component {
...
export default connect(mapStateToProps, establishConnection)(AuthenticatedApp);

我正在使用 Visual Studio代码(1.26.1) “ @ types / react”:“ ^ 16.4.13” “ @ types / react-dom”:“ ^ 16.0.7” “ typescript”:“ ^ 3.0.3”

谢谢!

HerrB92

1 个答案:

答案 0 :(得分:0)

作为起点,您将使用完全相同的connect调用表达式并将其手动应用于组件,而不是使用装饰器:

export default connect(({session: { loggedIn }}) => ({loggedIn}), {establishConnection})(AuthenticatedApp);

(并从类中删除export default。)由于TypeScript无法推断mapStateToProps函数的参数类型,现在您将得到一个(不是很清楚)错误。您可以这样注释它:

export default connect(({session: { loggedIn }}: {session: {loggedIn: boolean}}) => ({loggedIn}), {establishConnection})(AuthenticatedApp);
//                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

(也许您的代码库中已经定义了一个包含{session: {loggedIn: boolean}}甚至更多的类型。)

或者,您可以拉出mapStateToProps函数,将其保留为箭头函数:

const mapStateToProps =
  ({session: { loggedIn }}: {session: {loggedIn: boolean}}) => ({loggedIn});
export default connect(mapStateToProps, {establishConnection})(AuthenticatedApp);

或将其转换为传统的function定义:

function mapStateToProps({session: { loggedIn }}: {session: {loggedIn: boolean}}) {
  return {loggedIn};
}
export default connect(mapStateToProps, {establishConnection})(AuthenticatedApp);

最终,要成功编译该组件,您需要指定其props类型,如下所示:

class AuthenticatedApp extends React.Component<{establishConnection: () => void, loggedIn: boolean}> { ... }

但这是与connect不同的问题。