LoginSignup
17
11

More than 3 years have passed since last update.

typescript-fsaで作られるactionについて

Posted at

typescript-fsaしゅごい :sunflower:

なんでしゅごいのかは@m0aさんのこちらの記事が分かりやすいです。
FSAって何って方はこちら

この記事はtypescript-fsaによって作られるactionについて説明します。

Actionを作る :runner:

actionを作るにはまずactionCreatorを作ります

import actionCreatorFactory from 'typescript-fsa'

const actionCreator = actionCreatorFacory()

ここからactionを定義していきます

// typeが'HogeAction'かつpayloadの型がstringなFSA
const hogeAction = actionCreator<string>('hogeAction')
hogeAction.type
// 'hogeAction'
hogeAction('a')
// { type: 'hogeAction', payload: 'a' }

// payloadには型チェックが入る
hogeAction(1)
// error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.

// payload無し
const hugaAction = actionCreator<void>('hugaAction')
const piyoAction = actionCreator('piyoAction')

// error
const errorAction = actionCreator<Error>('errorAction')
errorAction(new Error('hoge')) 
// {
//   type: 'errorAction',
//   payload: Error: hoge
//       at /home/kc5m/src/localhost/kc5m/fsa-saga-sample/[eval].ts:1:13
//       // 省略
//   error: true  // Error型を渡すと自動的に{error: true}が付与される(条件変更可)
// }

非同期用Actionを作る :gear:

typescript-fsaには非同期処理向けに非同期用Actionをいい感じに作ってくれるAPIも用意されています。

AsyncActionCreator(AAC)と呼称されています。

実際にAACを定義してみます。

// AAC定義
const hogeAsyncAction = actionCreator.async<string, number, Error>('hogeAsyncAction')

actionCreator.async()Params, Result, Error(javascriptのError型とは別)の3つの型からstarted, done, failedの3つのAction(FSA)を生成します。

上記の例で言うとstringParams, numberResult, ErrorErrorに相当します。

生成された3つのActionは非同期処理での利用を想定されています。例えば以下の非同期関数があったとします。

const f = async (params: string): Promise<number> {
  const result = await someAsyncFunc(pars)
  if (!result) {
    throw new Error('error')
  }
  return 0
}

startedf()が実行されたタイミングを、donereturnされたタイミングを、そしてfailedthrowされたタイミングをそれぞれ表現していると考えると分かりやすいかも知れません。

さて、このAACですが通常のActionではないのでそのままActionとして使えません。

hogeAsyncAction('aaa')
// error TS2349: This expression is not callable.

そのためAAC内propertyに生成されたActionを使う必要があります。

// started
hogeAsyncAction.started('a')
// { type: 'hogeAsyncAction_STARTED', payload: 'a' }

startedと同じようにdonefailedを使うとerrorが出ます。

// done
hogeAsyhogeAsyncAction.done(2)
// error TS2345: Argument of type '2' is not assignable to parameter of type '{ params: string; } & { result: number; }'.

// failed
hogeAsyhogeAsyncAction.failed(new Error('hoge'))
// error TS2345: Argument of type 'Error' is not assignable to parameter of type '{ params: string; } & { error: Error; }'.

AACが作るdone, failedのpayloadの型は拡張されていて、payloadの中にstartedに渡したpayloadが含まれるようになっています。
上記の例で言うとerrorにも書かれていますがdone{ params: string } & { result: number }型に、failed{ params: string } & { error: Error }型になります。

hogeAsyncAction.done({ params: 'a', result: 1 })
// { type: 'hogeAsyncAction_DONE', payload: { params: 'a', result: 1 }}

hogeAsyncAction.failed({ params: 'a', error: new Error('aaa') })
// {
//   type: 'hogeAsyncAction_FAILED',
//   payload: {
//     error: Error: aaa
//         at /home/kc5m/src/localhost/kc5m/fsa-saga-sample/[eval].ts:1:33
//         // 省略
//     params: 'a'
//   },
//   error: true
// }

まとめると以下のようなります。

actionCreator.async<Params, Result, Error>()で作られるactionのpayloadの型は

  • started: Params
  • done: { params: Params } & { result: Result }
  • failed: { params: Params } & { error: Error }

また、doneResultError型(new Error()とか)が来てもerror: trueになりません。FAILEDErrorError型以外が来てもerror: trueになります。

const fugaAsyncAction = actionCreator.async<string, Error, string>('fugaAsyncAction')
fugaAsyncAction.done({result: new Error('aaa'), params: 'a'})
// {
//   type: 'fugaAsyncAction_DONE',
//   payload: {
//     result: Error: aaa
//         at /home/kc5m/src/localhost/kc5m/fsa-saga-sample/[eval].ts:1:32
//         // 省略
//     params: 'a'
//   }
// }

fugaAsyncAction.failed({error: 'a', params: 'a'})
// {
//   type: 'fugaAsyncAction_FAILED',
//   payload: { error: 'a', params: 'a' },
//   error: true
// }

最後に :rocket:

typescript-fsaを使うことによって、型チェックが走るFSAの定義及び非同期処理用に複数のFSAを少ない行数で定義できます。
これ単体だけでも便利ですが、同じ作者より提供されている以下のCompanion Packagesを併用することにより更に便利に使うことができます(リンク省略)。

  • typescript-fsa-redux-saga
  • typescript-fsa-redux-observable
  • typescript-fsa-redux-thunk
  • typescript-fsa-reducers

以上 :dash:

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11