Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inferred Types for Flux

Takepepe
August 03, 2018

Inferred Types for Flux

まぼろしのJS勉強会 #5 「型とテスト」https://maboroshi.connpass.com/event/93959/

Takepepe

August 03, 2018
Tweet

More Decks by Takepepe

Other Decks in Technology

Transcript

  1. Flux はいとも簡単に壊れる View / middleware の各所は State / Payload へ

    強依存 している。 規模が大きくなるにつれ 依存 が分散し、 リリース後、それは予測不能に陥る。
  2. Vuex が好き 型都合で普段は React を使っている。 でも Vuex や MobX ぐらいの

    「DX」が好き。 Redux は面倒なことが多いと思う。 Redux 嫌 -> Vuex 型NG -> ??? な人いそう ※ DX (Developer Experience = 開発者体験) ※
  3. Redux で +1 const initialState = { count: 0 }

    const types = { INCREMENT: 'COUNTER_INCREMENT' } const increment = () => ({ type: types.INCREMENT }) function reducer(state = initialState, action) { switch (action.type) { case types.INCREMENT: return { ...state, count: state.count++ } default: return state } } Redux DX の悪さ
  4. Vuex で +1 const state = { count: 0 }

    const mutations = { increment (state) { state.count++ } } Vuex DX の良さ
  5. redux-aggregate で +1 const state = { count: 0 }

    const mutations = { increment (state) { return { ...state, count: state.count++ } } } 輸入する Vuex DX の良さ
  6. type A1<T> = T extends (a1: infer I, ...rest: any[])

    => any ? I : never type A2<T> = T extends (a1: any, a2: infer I, ...rest: any[]) => any ? I : never type MT<T> = (state: A1<T>) => A1<T> type MTPL<T> = (state: A1<T>, payload: A2<T>) => A1<T> type CR<T> = () => { type: string } type CRPL<T> = (payload: A2<T>) => { type: string; payload: A2<T> } type Mutation<T> = MT<T> | MTPL<T> type Creator<T> = T extends MT<T> ? CR<T> : CRPL<T> 推論マッピング型(redux-aggregate 抜粋)
  7. type A1<T> = T extends (a1: infer I, ...rest: any[])

    => any ? I : never type A2<T> = T extends (a1: any, a2: infer I, ...rest: any[]) => any ? I : never type MT<T> = (state: A1<T>) => A1<T> type MTPL<T> = (state: A1<T>, payload: A2<T>) => A1<T> type CR<T> = () => { type: string } type CRPL<T> = (payload: A2<T>) => { type: string; payload: A2<T> } type Mutation<T> = MT<T> | MTPL<T> // 入力型を制限する type Creator<T> = T extends MT<T> ? CR<T> : CRPL<T> // 出力型のアサーションに利用 推論マッピング型(redux-aggregate 抜粋)
  8. 型定義・キャストは最小限。型付けは完璧に。 新たに mutation 関数を追加すれば、 ActionType / ActionCreator は自動で追加。 mutation 関数の

    Payload スキーマを変更すると、 末端の View までエラーが行き渡る。 ※1. Mapped types & Lookup types / ※2. Type inference in conditional types ※2 ※1