Redux を勉強中で試しに書いてみたのですが、動作はしたもののコンパイラーがエラーを吐いていてどう解決すればよいかわかりません。どなたかアドバイスをいただけると嬉しいです。
環境
"react": "16.13.1", "react-dom": "16.13.1", "redux":"4.0.5", "react-redux":"7.2.0", "typescript-fsa": "3.0.0", "typescript-fsa-reducers":"1.2.1" "@types/react-redux":"7.1.7",
エラー
connect(App)
にて
class App Argument of type 'typeof App' is not assignable to parameter of type 'ComponentType<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__ScratchPanel & { ...; }> | Matching<...> | Matching<...> | Matching<...> | Matching<...>>'. Type 'typeof App' is not assignable to type 'ComponentClass<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__ScratchPanel & { ...; }> | Matching<...> | Matching<...> | Matching<...> | Matching<...>, any>'. Construct signature return types 'App' and 'Component<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__ScratchPanel & { ...; }> | Matching<...> | Matching<...> | Matching<...> | Matching<...>, any, any>' are incompatible. The types of 'props' are incompatible between these types. Type '(Readonly<I__AppProps & I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>)' is not assignable to type '(Readonly<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__ScratchPanel & { ...; }>> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>)'. Type 'Readonly<I__AppProps & I__CreateCardPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }> & Readonly<...>' is not assignable to type '(Readonly<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__ScratchPanel & { ...; }>> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>) | (Readonly<...> & Readonly<...>)'. Type 'Readonly<I__AppProps & I__CreateCardPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }> & Readonly<...>' is not assignable to type 'Readonly<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__SettingPanel & { ...; }>> & Readonly<...>'. Type 'Readonly<I__AppProps & I__CreateCardPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }> & Readonly<...>' is not assignable to type 'Readonly<Matching<I__ScratchPanel & { changeWidget: (v: T__WidgetState) => Action<T__WidgetState>; }, I__AppProps & I__SettingPanel & { ...; }>>'. Types of property 'panel' are incompatible. Type '"createCardPanel"' is not assignable to type '"scratchPanel"'.ts(2345) Peek Problem No quick fixes available
connect(App as any)
とすると消えるので、型関係だと思うのですが…
ソースコード
- App.tsx
tsx
1import * as React from 'react'; 2import {Dispatch} from 'redux'; 3import {Action} from 'typescript-fsa'; 4import {ReduxPack} from '@SRC/redux/index'; 5import {connect} from 'react-redux'; 6 7interface I__AppProps{ 8 9} 10 11interface I__AppStates{ 12 13} 14 15type Props = I__AppProps & ReduxPack.Type.T__Widget & ReturnType<typeof mapDispatchToProps> 16 17class App extends React.Component<Props,I__AppStates>{ 18 constructor(props:Props){ 19 super(props); 20 this.state = {} 21 } 22 23 render(){ 24 return ( 25 <div data--component-class="App"> 26 <div>{this.props.panel} - {this.props.mode}</div> 27 <button onClick={()=>this.props.changeWidget({panel:'createCardPanel',mode:'attachmentMode'})}></button> 28 </div> 29 ) 30 } 31} 32 33 34// connect 35 36function mapDispatchToProps(dispatch:Dispatch<Action<any>>){ 37 return { 38 changeWidget:(v:ReduxPack.Type.T__Widget)=>dispatch(ReduxPack.Actions.widget.changeWidget(v)) 39 } 40} 41 42function mapStateToProps(storeState:ReduxPack.Type.T__StoreState){ 43 return Object.assign({},storeState.widget) 44} 45 46export const APP = connect(mapStateToProps,mapDispatchToProps)(App);
- index.tsx
tsx
1import * as React from 'react'; 2import * as ReactDOM from 'react-dom'; 3import {ReduxPack} from '@SRC/redux/index'; 4import {Provider} from 'react-redux'; 5import {APP} from '@SRC/components/App'; 6import './index.html'; 7ReactDOM.render(<Provider store={ReduxPack.store}><APP/></Provider>,document.getElementById('root'));
- @src/redux/index.ts
ts
1import {combineReducers,createStore,Dispatch} from 'redux'; 2import * as widgetReducer from './modules/widgetReducer'; 3 4const rootReducer = combineReducers({ 5 widget:widgetReducer.widgetReducer 6}) 7 8 9export namespace ReduxPack{ 10 export const store = createStore(rootReducer); 11 export namespace Actions{ 12 export const widget = widgetReducer.widgetActions 13 } 14 export namespace Type{ 15 export type T__Widget = widgetReducer.T__WidgetState 16 export type T__StoreState = ReturnType<typeof rootReducer>; 17 18 } 19}
- widgetReducer.ts
ts
1import {reducerWithInitialState} from 'typescript-fsa-reducers'; 2import {actionCreatorFactory} from 'typescript-fsa'; 3const actionCreator = actionCreatorFactory(); 4 5interface I__ScratchPanel{ 6 panel:'scratchPanel'; 7 mode: 'default'; 8} 9 10interface I__CreateCardPanel{ 11 panel:'createCardPanel'; 12 mode:'viewMode'|'contentMode'|'attributeMode'|'escapeMode'|'attachmentMode' 13} 14 15interface I__FindCardPanel{ 16 panel:'findCardPanel'; 17 mode:'searchMode'|'viewMode'; 18} 19 20interface I__StudyCardPanel{ 21 panel:'studyCardPanel'; 22 mode: 'configMode'|'studyMode' 23} 24 25interface I__SettingPanel{ 26 panel:'settingsPanel'; 27 mode: 'default'; 28} 29 30type T__WidgetState = I__ScratchPanel|I__CreateCardPanel|I__FindCardPanel|I__StudyCardPanel|I__SettingPanel; 31 32 33 34const initialWidgetState:T__WidgetState ={ 35 panel:'scratchPanel', 36 mode:'default' 37} 38 39const widgetActions = { 40 changeWidget:actionCreator<T__WidgetState>('CHANGE_WIDGET') 41} 42 43const widgetReducer = reducerWithInitialState(initialWidgetState) 44 .case(widgetActions.changeWidget,(state,payload)=>{ 45 const newState = Object.assign({},state,payload); 46 return newState; 47 }) 48 .default((state,payload)=>{ 49 return state 50 }) 51 52export {T__WidgetState,widgetActions,widgetReducer};
あなたの回答
tips
プレビュー