我尝试使用redux和react-router- dom在打字稿中构建一个React应用程序。当我在应用程序中添加redux时遇到输入问题。因此,我创建了以下仅包含一页 test-page的 最小示例:
App.jsx
import * as React from 'react'; import { Route, Redirect } from 'react-router-dom' import Test from './containers/test-page' import './App.css'; class App extends React.Component { render() { return ( <div className="ui container" id="main"> <Route exact path="/" render={() => <Redirect to="/test" />}/> <Route exact path="/test" component={Test} /> </div> ); } } export default App;
测试页面的容器如下所示。它会在 connect 的调用中产生键入错误。
容器/测试页/index.tsx
import { Dispatch } from 'redux' import { connect } from 'react-redux' import TestPage from './test-page' function mapDispatchToProps(dispatch: Dispatch<any>) { return dispatch({ type: 'ALERT_USER' }); } function mapStateToProps(state: any) { return { label: 'my test label' } } export default connect( mapStateToProps, mapDispatchToProps )(TestPage)
容器使用以下react组件,在生产中应将其呈现为路由器的页面。它产生两个错误,请参见下文。
容器/测试页面/测试页面.tsx
import * as React from 'react'; export namespace Test { export interface Props { alert: () => void; label: string; } export interface State { } } export default class TestPage extends React.Component { constructor(props?: Test.Props, state?: Test.State, context?: any) { super(props, context); } sendAlert = () => { this.props.alert() } render() { return ( <div> <h1>Test</h1> <button onClick={this.sendAlert}>{this.props.label}</button> </div> ); } }
proxyConsole.js:54 ./src/containers/test-page/test-page.tsx (20,18): error TS2339: Property 'alert' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'. proxyConsole.js:54 ./src/containers/test-page/test-page.tsx (27,54): error TS2339: Property 'label' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'. proxyConsole.js:54 ./src/containers/test-page/index.tsx (16,3): error TS2345: Argument of type 'typeof TestPage' is not assignable to parameter of type 'ComponentType<{ label: string; } & { type: string; }>'. Type 'typeof TestPage' is not assignable to type 'StatelessComponent<{ label: string; } & { type: string; }>'. Type 'typeof TestPage' provides no match for the signature '(props: { label: string; } & { type: string; } & { children?: ReactNode; }, context?: any): ReactElement<any> | null'.
我尝试遵循不同的指南,并查找示例实现,但无法解决这些问题。我不了解打字稿编译器的错误消息:
this.props
我注意到几件事:
1)据我在示例中看到的以及props在TypeScript中使用时,您对的调用React.Component需要Props像这样指定类型参数:
props
React.Component
Props
export default class TestPage extends React.Component<Test.Props, Test.State>{ constructor(props: Test.Props) { super(props); } }
您可以指定您的组件不接受props或state通过传递空接口,即:
state
export default class TestPage extends React.Component<{}, {}>{ // constructor becomes 'useless' at this point and is not needed constructor() { super(); } }
我认为这可以解释您的呼叫签名不匹配的原因,以及为什么看不见任何属性this.props-TS看到一个接口,ReadOnly{}因为它没有传入类型参数。
ReadOnly{}
2)您的mapStateToProps功能看起来不太正确。mapStateToProps接受两个参数state((引用您的Redux store)和ownProps作为可选的第二个参数,该参数引用props从父级传递过来的参数)。因此mapStateToProps应如下所示:
mapStateToProps
store
ownProps
function mapStateToProps(state: any, ownProps: { label: string }) { return { label: ownProps.label }; }
这是我为什么connect会引发错误的猜测- 在这里,您只是断言Redux应该如何处理props来自store和props来自父代的合并。让我知道是否可行。
connect