2017-12-04 1 views
1

연결된 구성 요소에 유형을 지정하지 않고 작업을 계속하기 위해 고심하고 있습니다.Redux, React 및 TypeScript를 사용하여 연결된 구성 요소에서 작업 작성자 유형을 유지 관리하는 방법은 무엇입니까?

기본적으로 많은 redux 작업 제작자를 가져 오면 react-redux을 사용하여 디스패처로 감싸고 구성 요소에 전달합니다. 결과 작업에서 가져온 기능의 원래 유형 정보를 유지하고 싶습니다.

조치 유형을 가지고 반환 형식 유추된다

export const actionA = (p1: string, p2: number) => 
    ({ type: 'EXAMPLE_A', payload: { p1, p2 } }) 

export const actionB = (p1: number) => 
    ({ type: 'EXAMPLE_B', payload: p1 }) 

하지만 내 구성 요소가 여전히 유형의 안전을 잃고, 컴파일러를 충족하기 위해 몇 가지 any 종류가 있습니다.

import * as React from 'react' 
import { Dispatch, bindActionCreators } from 'redux' 
import { connect } from 'react-redux' 
import * as exampleActions from '../actions/example' 

interface MyComponentProps { 
    someStore: SomeStoreState, 
    actions: any // <-- Just use whatever types exampleActions have? 
} 

class MyComponent extends React.Component<MyComponentProps, {}> { 

    constructor(props: MyComponentProps) { 
    super(props) 
    } 

    private foo() { 
    const { actionA } = this.props.actions.exampleActions 
    actionA('foo', 'bar') // <-- Compile time error pls 
    } 


    public render() { 
    return null 
    } 

} 

const mapStateToProps = (state: RootState) => ({ 
    someStore: state.someStore 
}) 

const mapDispatchToProps = (dispatch: Dispatch<any>) => ({ 
    actions: { 
    exampleActions: bindActionCreators<any>(exampleActions, dispatch) 
    } 
}) 

export default connect (mapStateToProps, mapDispatchToProps)(MyComponent) 

인터페이스는 그렇다고하는 데 도움이 소품에 다시 함수 매개 변수 유형을 선언,하지만 난 단지 그들이 한 장소에 정의되어 있으므로 원래의 형태를 유지하고 싶습니다.

디스패처 자체의 유형에 대해서는별로 신경 쓰지 않으므로 exampleTypes (및 기타 조치의) 유형 정보를 소품으로 캐스팅하는 것이 나에게 충분한 해결책이 될 것입니다. 그곳에 창조자가 소품으로 버려졌다.

또한 응용 프로그램에서 redux-promise-middleware을 사용하고 있는데, 이는 일부 동작이 약속을 반환 할 수 있음을 의미합니다. 또한 해당 정보가 보존되기를 원하기 때문에 구성 요소 내에서 작업을 체인화 할 수 있습니다. 하지만 캐스팅을 시작할 때는 문제가되지 않아야한다고 생각합니다.

+1

이 라이브러리를 확인하십시오. https://github.com/aikoven/typescript-fsa – MistyK

답변

1

명시 적으로 작업 작성자를 입력 한 다음 함수 자체와 함께 유형을 가져와야합니다. 일반적인 액션 인터페이스를 만드는 것이 도움이 될 수 있습니다. 일반적으로 redux 유형 자체는 도움이되지 않습니다. 조금 자세하게 설명 하겠지만 유형 지원은 가치있는 경우가 많습니다. 특히 감속기 내에서 우수한 입력을 얻을 수있는 경우에 특히 그렇습니다.

나는 일반적으로 행동/제작자에 대한이 같은 것을 사용 :

와 같은 구성 요소에서 사용할 수있는
export interface TypedAction<TAction, TPayload> { 
    type: TAction; 
    payload: TPayload; 
} 

export type TypeA = "EXAMPLE_A"; 
export type TypeB = "EXAMPLE_B"; 

export interface PayloadA { 
    p1: string; 
    p2: number; 
} 

export interface PayloadB { 
    p1: number; 
} 

export type ActionA = TypedAction<TypeA, PayloadA>; 
export type ActionB = TypedAction<TypeB, PayloadB>; 

export type Actions = ActionA | ActionB; 

export type ActionCreatorA = (p1: string, p2: number) => ActionA; 

export type ActionCreatorB = (p1: number) => ActionB; 

export const actionCreatorA: ActionCreatorA = (p1, p2) => ({ 
    type: "EXAMPLE_A", 
    payload: { 
     p1, 
     p2 
    } 
});  

export const actionCreatorB: ActionCreatorB = (p1) => ({ 
    type: "EXAMPLE_B", 
    payload: { 
     p1 
    } 
}); 

:

import * as React from 'react' 
import { Dispatch, bindActionCreators } from 'redux' 
import { connect } from 'react-redux' 
import { 
    actionCreatorA, ActionCreatorA, 
    actionCreatorB, ActionCreatorB 
} from '../actions/example' 

interface MyComponentProps { 
    someStore: SomeStoreState; 
    actionCreatorA: ActionCreatorA; 
    actionCreatorB: ActionCreatorB; 
} 

class MyComponent extends React.Component<MyComponentProps, {}> { 

    constructor(props: MyComponentProps) { 
     super(props) 
    } 

    private foo() { 
     const { actionA } = this.props; 
     actionA('foo', 'bar') // <-- Compiles 
    } 


    public render() { 
     return null 
    } 

} 

const mapStateToProps = (state: RootState) => ({ 
    someStore: state.someStore 
}) 

const mapDispatchToProps = { 
    actionCreatorA 
}; 

export default connect (mapStateToProps, mapDispatchToProps)(MyComponent) 
또한 사용하여 혜택을 누릴 수 있습니다

기어 :

import (Actions } from "./actions/example"; 

// Actions here is the union type of all actions this reducer will 
// handle, as exported from the actions file 
export const someReducer = (state = defaultState, action: Actions) => { 
    switch (action.type) { 
     case "EXAMPLE_A": 
      // action is typed as ActionA 
      return { 
       p1: action.p1, 
       p2: action.p2 
      }; 
     case "EXAMPLE_B": 
      // action is typed as ActionB 
      return { 
       p1: action.p1, 
       p2: action.p2 // <-- Does not compile, p2 does not exist on ActionB 
      }; 
     default: 
      return state; 
    } 
} 
+0

감사합니다. 도움이 되겠지만 아직이 문제를 해결하는 다른 방법이 있다면 대답으로 받아 들일 수 없습니다. 내가 기본적으로 가져온 액션 크리에이터에 대한 매개 변수 유형 정보를 원할 때 실제 디스패치 프로세스에서 유형 안전성에별로 신경 쓰지 않으면 서 연결된 액션의 매개 변수가 일치하기 때문에 상당한 양의 상용구처럼 보입니다. 어쩌면 더 쉽게 처리 할 방법이 없겠지만 계속 찾고있을 것입니다. – Voidsheep

관련 문제