使用React和TypeScript时如何正确键入@connect?

时间:2017-01-31 21:01:01

标签: reactjs typescript redux typescript2.0

我一直在努力解决这个问题的时间最长。今天坐下来致力于摆脱任何Layer (type) Output Shape Param # Connected to ==================================================================================================== dense_1 (Dense) (None, 16384) 1654784 dense_input_1[0][0] ____________________________________________________________________________________________________ batchnormalization_1 (BatchNorma (None, 16384) 65536 dense_1[0][0] ____________________________________________________________________________________________________ activation_1 (Activation) (None, 16384) 0 batchnormalization_1[0][0] ____________________________________________________________________________________________________ reshape_1 (Reshape) (None, 1024, 4, 4) 0 activation_1[0][0] ____________________________________________________________________________________________________ upsampling2d_1 (UpSampling2D) (None, 1024, 8, 8) 0 reshape_1[0][0] ____________________________________________________________________________________________________ convolution2d_1 (Convolution2D) (None, 512, 8, 8) 13107712 upsampling2d_1[0][0] ____________________________________________________________________________________________________ batchnormalization_2 (BatchNorma (None, 512, 8, 8) 32 convolution2d_1[0][0] ____________________________________________________________________________________________________ activation_2 (Activation) (None, 512, 8, 8) 0 batchnormalization_2[0][0] ____________________________________________________________________________________________________ upsampling2d_2 (UpSampling2D) (None, 512, 16, 16) 0 activation_2[0][0] ____________________________________________________________________________________________________ convolution2d_2 (Convolution2D) (None, 256, 16, 16) 3277056 upsampling2d_2[0][0] ____________________________________________________________________________________________________ batchnormalization_3 (BatchNorma (None, 256, 16, 16) 64 convolution2d_2[0][0] ____________________________________________________________________________________________________ activation_3 (Activation) (None, 256, 16, 16) 0 batchnormalization_3[0][0] ____________________________________________________________________________________________________ upsampling2d_3 (UpSampling2D) (None, 256, 32, 32) 0 activation_3[0][0] ____________________________________________________________________________________________________ convolution2d_3 (Convolution2D) (None, 128, 32, 32) 819328 upsampling2d_3[0][0] ____________________________________________________________________________________________________ batchnormalization_4 (BatchNorma (None, 128, 32, 32) 128 convolution2d_3[0][0] ____________________________________________________________________________________________________ activation_4 (Activation) (None, 128, 32, 32) 0 batchnormalization_4[0][0] ____________________________________________________________________________________________________ upsampling2d_4 (UpSampling2D) (None, 128, 64, 64) 0 activation_4[0][0] ____________________________________________________________________________________________________ convolution2d_4 (Convolution2D) (None, 64, 64, 64) 204864 upsampling2d_4[0][0] ____________________________________________________________________________________________________ batchnormalization_5 (BatchNorma (None, 64, 64, 64) 256 convolution2d_4[0][0] ____________________________________________________________________________________________________ activation_5 (Activation) (None, 64, 64, 64) 0 batchnormalization_5[0][0] ____________________________________________________________________________________________________ convolution2d_5 (Convolution2D) (None, 3, 64, 64) 4803 activation_5[0][0] ____________________________________________________________________________________________________ activation_6 (Activation) (None, 3, 64, 64) 0 convolution2d_5[0][0] ==================================================================================================== Total params: 19,134,563 Trainable params: 19,101,555 Non-trainable params: 33,008 ____________________________________________________________________________________________________ ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== convolution2d_6 (Convolution2D) (None, 64, 32, 32) 4864 convolution2d_input_1[0][0] ____________________________________________________________________________________________________ leakyrelu_1 (LeakyReLU) (None, 64, 32, 32) 0 convolution2d_6[0][0] ____________________________________________________________________________________________________ convolution2d_7 (Convolution2D) (None, 128, 16, 16) 204928 leakyrelu_1[0][0] ____________________________________________________________________________________________________ leakyrelu_2 (LeakyReLU) (None, 128, 16, 16) 0 convolution2d_7[0][0] ____________________________________________________________________________________________________ convolution2d_8 (Convolution2D) (None, 256, 8, 8) 819456 leakyrelu_2[0][0] ____________________________________________________________________________________________________ leakyrelu_3 (LeakyReLU) (None, 256, 8, 8) 0 convolution2d_8[0][0] ____________________________________________________________________________________________________ convolution2d_9 (Convolution2D) (None, 512, 4, 4) 3277312 leakyrelu_3[0][0] ____________________________________________________________________________________________________ leakyrelu_4 (LeakyReLU) (None, 512, 4, 4) 0 convolution2d_9[0][0] ____________________________________________________________________________________________________ flatten_1 (Flatten) (None, 8192) 0 leakyrelu_4[0][0] ____________________________________________________________________________________________________ dense_2 (Dense) (None, 1024) 8389632 flatten_1[0][0] ____________________________________________________________________________________________________ leakyrelu_5 (LeakyReLU) (None, 1024) 0 dense_2[0][0] ____________________________________________________________________________________________________ dropout_1 (Dropout) (None, 1024) 0 leakyrelu_5[0][0] ____________________________________________________________________________________________________ dense_3 (Dense) (None, 2) 2050 dropout_1[0][0] ==================================================================================================== Total params: 12,698,242 Trainable params: 12,698,242 Non-trainable params: 0 ____________________________________________________________________________________________________ ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== input_2 (InputLayer) (None, 100) 0 ____________________________________________________________________________________________________ sequential_1 (Sequential) (None, 3, 64, 64) 19134563 input_2[0][0] ____________________________________________________________________________________________________ sequential_2 (Sequential) (None, 2) 12698242 sequential_1[1][0] ==================================================================================================== Total params: 31,832,805 Trainable params: 31,799,797 Non-trainable params: 33,008 ____________________________________________________________________________________________________ Pre-training generator... 左,但没有成功。

any

在上面的代码中,我得到以下内容:

import * as React from 'react';
import * as Redux from 'redux';
import { connect } from 'react-redux';
import { ReduxState } from './types';
import { syncItem, displayAlert } from './actionCreators';
import { SyncItemAction, DisplayAlertAction } from './actions';

// Props coming from Redux using `connect` and `mapStateToProps`
type AppData = {
    isSelected: boolean;
    isInEditMode: boolean;
};

// Action creators from `./actionCreators` all wrapped in `dispatch` using `connect` and `mapDispatchToProps`
type AppActions = {
    syncItem: (id: number) => SyncItemAction;
    displayAlert: (text: string) => DisplayAlertAction;
};

// Actual JSX attributes that will be required by the type system.
type AppProps = {
    id: number;
    name: string;
} & Partial<AppData> & Partial<AppActions>; // Making data and actions partial so that using <App /> in JSX doesn't yell.

// The component's inner state.
type AppState = Partial<{
    temp: string;
}>;

@connect<AppData, AppActions, AppProps>(mapStateToProps, mapDispatchToProps)(App) // Or mapDispatchToPropsAlt
export default class App extends React.Component<AppProps, AppState> {
    constructor(props: AppProps) {
        super(props);
    }

    render() {
        return (
            <div>
                <h1>Hello, {this.props.name}! (#{this.props.id})</h1>
                {/* In the below, syncItem should take the new name, a detail… Also ID could be provided in `mapStateToProps` by using `ownProps`! */}
                Rename: <input value={this.state.temp} onChange={event => this.setState({ temp: event.target.value })} />
                <button onClick={_ => this.props.syncItem(this.props.id)}>Sync</button>
            </div>
        );
    }
}

function mapStateToProps(state: ReduxState, ownProps?: AppProps): AppData {
    return {
        isSelected: ownProps.id === state.selectedId,
        isInEditMode: state.isInEditMode
    };
}

function mapDispatchToProps(dispatch: Redux.Dispatch<ReduxState>, ownProps?: AppProps): AppActions {
    return {
        syncItem: (id: number) => dispatch(syncItem(id)),
        displayAlert: (text: string) => dispatch(displayAlert(text, ownProps.name))
    };
}

function mapDispatchToPropsAlt(dispatch: Redux.Dispatch<ReduxState>, ownProps?: AppProps): AppActions {
    return {
        syncItem,
        // Making this `null` because `displayAlert` above changes the signature by hiding the other parametr and taking it from `ownProps` - uncommon!
        displayAlert: null
    };
}

function Test() {
    // Only `id` and `name` is correctly required.
    return <App id={0} name={'test'} />;
}

我已经使用index.tsx(31,78): error TS2345: Argument of type 'typeof App' is not assignable to parameter of type 'ComponentClass<AppData & AppActions> | StatelessComponent<AppData & AppActions>'. Type 'typeof App' is not assignable to type 'StatelessComponent<AppData & AppActions>'. Type 'typeof App' provides no match for the signature '(props: AppData & AppActions & { children?: ReactNode; }, context?: any): ReactElement<any>' 中的类型定义来提出我上面提到的内容,同样我已经检查了node_modules/@types的样子。它建议(在我看来)该组件的ComponentClass<T>必须是state,我不明白为什么会这样,如果我将上面的代码更改为{{1}或{} | void它不会以任何方式更改第一个错误。

我应该怎么做?

<AppProps, void>仅为<AppProps, {}>syncItemfunction syncItem(id: number): SyncItemAction,与SyncItemAction类似。

修改:找到了related question,但这个问题并没有回答interface SyncItemAction extends Redux.Action { id: number; }的输入方式。

1 个答案:

答案 0 :(得分:1)

这个答案不使用注释(并使用接口而不是类型)。基本思想是将Connected组件及其props与底层组件完全分开(明智地说明)。

创建一个类ConnectedAppProps,它们是您要向提供者公开的连接组件的属性

interface ConnectedAppProps {
    id: number;
    name: string;
}

从该界面扩展AppProps

interface AppProps extends ConnectedAppProps, AppData, AppActions {
}

创建ConnectedComponent

const ConnectedApp: React.ComponentClass<ConnectedAppProps> = 
    connect<AppData,AppActions,AppProps>( mapStateToProps, mapDispatchToProps )( App )

使用Provider下的已连接组件及其ConnectedAppProps

   <Provider store={store}>
       <ConnectedApp id={0} name={'test'} />
   </Provider>

今天点击时使用mapStateToPropmapDispatchToProps来“充实”AppProps

中的ConnectedAppProps组件// routes/request-location.js import Ember from 'ember'; import config from '../config/environment'; export default Ember.Route.extend({ model() { var key = config.myApiKey; var location = "denver"; var url = 'http://api.openweathermap.org/data/2.5/weather?q=' + location + '&appid=' + key; return new Ember.RSVP.Promise(function(resolve){ Ember.$.getJSON(url).then((responseJSON) => { resolve([responseJSON]); }); }); } });