【发布时间】:2017-09-06 09:17:53
【问题描述】:
我想用 flowtype 编写 redux,但我对如何做到这一点有疑问。
Redux 与 Flowtype
type ActionType =
| 'A'
| 'B'
;
// A generic type conforming to Flux Standard Action
type ActionT<A, P> = {|
type: A,
payload?: P | Error,
error?: boolean,
meta?: mixed
|};
type Action =
| ActionT<'A', string>
| ActionT<'B', number>
;
const error: Error = new Error('wrong');
const info = { href: '...' };
// ---- valid actions with flowtype ----
const action1: Action = {type: 'A', payload: 'hello' };
const action2: Action = {type: 'A', payload: error, error: true }; // The 'payload' could be an error.
const action3: Action = {type: 'A', payload: 'hello', meta: info }; // We can have 'meta'.
// ---- invalid actions with flowtype ----
const actionNG1: Action = {type: 'C', payload: 'hello' }; // Wrong 'type' value. The type 'C' is not allowed.
const actionNG2: Action = {type: 'B', payload: 'hello' }; // Wrong value type of 'payload'. It should be a number.
const actionNG3: Action = {type: 'A', payload: 'hello', threshold: 3 }; // Extra property 'threshold' is not allowed. It should conform to type ActionT.
- 我使用
ActionType而不是常量来检查有效的type值。 -
ActionT类型符合 Flux Standard Action 以确保 Redux 操作的结构。 -
Action类型声明了我们将在应用中使用的所有操作的具体类型。
问题 1:如何确保传递给ActionT 的第一个类型是ActionType 的类型(或者至少应该是string 类型)?
例如,不允许在其中添加新类型'C',因为ActionType 只接受'A' 和'B'。
type ActionType =
| 'A'
| 'B'
;
type Action =
| ActionT<'A', string>
| ActionT<'B', number>
| ActionT<'C', number> // Should Raise an error
;
有意义吗?
问题 2:如何使用 flowtype 和 Immutable.js 编写 reducers(和 thunk)?
我编写了一个 buildReducer 来绑定到初始状态。
type Action =
| ActionT<'SELECT_COUNTRY', string>
;
const buildReducer = (initialState, reducerMap) =>
(state = initialState, action) => {
const reducer = reducerMap[action.type];
return (reducer) ? reducer(state, action) : state;
};
const initialState = Immutable.fromJS({
selectedCountry: 'US'
})
const reducers = {
['SELECT_COUNTRY']: (state, action) => {
// how to know the type of payload is string type?
// how to ensure that `state.set(...)` gets right type of the value for the key?
return state.set('selectedCountry', action.payload)
}
}
const appReducer = buildReducer(initialState, reducers)
如何检查 reducers 中的 payload 类型以获取带有 flowtype 的操作类型 SELECT_COUNTRY?
如何通过流类型检查将有效负载值应用于immutable 状态?
【问题讨论】: