動機
PR #251 (createScanAction.test.ts の vi.fn() typing 統一) の /simplify pass 2 副産物として発見した refactor 候補。
src/stores/createScanAction.ts の CreateScanActionOptions.api field は () => (...args: TArgs) => Promise<TResult> という inline thunked signature を持つ。これを ScanApi<TArgs, TResult> という named type alias として切り出し export することで、
- 型の意図を docstring 付きで明示できる (現在の
api field 上の長文 doc comment は型の概念ではなく field の使い方を説明している)
- 将来 scan 系 helper (別 store factory / mocks utility 等) を増やした際の参照点を確保できる
- caller サイト (
src/stores/backlink.ts / src/stores/wikilink.ts) / test mock で type assertion / satisfies に使える余地を残す
現状
src/stores/createScanAction.ts:6-21:
interface CreateScanActionOptions<TState extends ScanStateBase, TArgs extends unknown[], TResult> {
/**
* scan 実行時に毎回呼ばれる thunk。中で実 API 関数を返す。
*
* thunk にしているのは store 評価時に `commands` からシンボルを直接読み出すと、
* 関係ない hooks/components のテストが `vi.mock("../lib/commands", () => ({ ... }))` で
* 一部の export しか mock していない場合に strict-mock エラーが出るのを避けるため。
* thunk 内の `commands` への参照は ES module の live binding で scan 呼び出し時に解決される。
*/
api: () => (...args: TArgs) => Promise<TResult>;
// ...
}
caller サイト:
src/stores/backlink.ts:23: api: () => scanBacklinks
src/stores/wikilink.ts:59: api: () => scanUnresolvedWikilinks
caller は createScanAction<TState, TArgs, TResult>(...) の generic で TArgs / TResult を渡しており、api field の型は generic 推論で互換性確保済。
修正案
Option A (推奨): createScanAction.ts のみ変更
/**
* scan 実行時に毎回呼ばれる thunk。中で実 API 関数を返す。
*
* thunk にしているのは ...(既存 doc を ScanApi 側へ移動)
*/
export type ScanApi<TArgs extends unknown[], TResult> = () => (
...args: TArgs
) => Promise<TResult>;
interface CreateScanActionOptions<TState extends ScanStateBase, TArgs extends unknown[], TResult> {
api: ScanApi<TArgs, TResult>;
// ...
}
- doc comment は
ScanApi 側に集約 (型 alias 自身の意味を説明する役割が適切)
- caller / test 変更不要
- Diff: 1 file、+5 -1 程度
Option B: caller サイトでも ScanApi 注釈を強制
// src/stores/backlink.ts
import { createScanAction, type ScanApi } from "./createScanAction";
const backlinkScanApi: ScanApi<[string, string], BacklinkSource[]> = () => scanBacklinks;
scan: createScanAction<BacklinkState, [string, string], BacklinkSource[]>({
api: backlinkScanApi,
// ...
}),
- caller サイトで type alias を明示活用
scanBacklinks signature 変更時に caller variable レベルでも検出
- Diff: 3 file (createScanAction.ts / backlink.ts / wikilink.ts)、+15 -3 程度
Option A を推奨する根拠
createScanAction<TState, TArgs, TResult> の generic で既に caller サイトの型推論が機能しており、api: () => scanBacklinks の inline 形式が () => (...args: TArgs) => Promise<TResult> と整合するか型レベルで検証される。Option B の variable 注釈は冗長
- caller サイトの可読性 (inline
api: () => scanBacklinks の宣言的さを維持)
- scope 最小化。将来 ScanApi を他箇所で活用する必要が生じた時に Option B へ漸進的に拡張可能
影響範囲
src/stores/createScanAction.ts: +5 -1 (type alias 追加 + api field 型置換、doc comment の移動)
caller / test は変更なし:
src/stores/backlink.ts: 変更なし
src/stores/wikilink.ts: 変更なし
src/stores/createScanAction.test.ts: 変更なし
Tier 推定
Tier B (defect-detection 強化、impact 小〜中、scope 小)
- 既存の generic 型推論で defect-detection は既に機能しているため、本 PR の直接 impact は「将来 helper 追加時の参照点確保」「型の意図文書化」が主
- scope は最小変更 (Option A) で 1 file +5 -1 程度
動機
PR #251 (createScanAction.test.ts の vi.fn() typing 統一) の
/simplifypass 2 副産物として発見した refactor 候補。src/stores/createScanAction.tsのCreateScanActionOptions.apifield は() => (...args: TArgs) => Promise<TResult>という inline thunked signature を持つ。これをScanApi<TArgs, TResult>という named type alias として切り出し export することで、apifield 上の長文 doc comment は型の概念ではなく field の使い方を説明している)src/stores/backlink.ts/src/stores/wikilink.ts) / test mock で type assertion / satisfies に使える余地を残す現状
src/stores/createScanAction.ts:6-21:caller サイト:
src/stores/backlink.ts:23:api: () => scanBacklinkssrc/stores/wikilink.ts:59:api: () => scanUnresolvedWikilinkscaller は
createScanAction<TState, TArgs, TResult>(...)の generic でTArgs/TResultを渡しており、apifield の型は generic 推論で互換性確保済。修正案
Option A (推奨): createScanAction.ts のみ変更
ScanApi側に集約 (型 alias 自身の意味を説明する役割が適切)Option B: caller サイトでも ScanApi 注釈を強制
scanBacklinkssignature 変更時に caller variable レベルでも検出Option A を推奨する根拠
createScanAction<TState, TArgs, TResult>の generic で既に caller サイトの型推論が機能しており、api: () => scanBacklinksの inline 形式が() => (...args: TArgs) => Promise<TResult>と整合するか型レベルで検証される。Option B の variable 注釈は冗長api: () => scanBacklinksの宣言的さを維持)影響範囲
src/stores/createScanAction.ts: +5 -1 (type alias 追加 +apifield 型置換、doc comment の移動)caller / test は変更なし:
src/stores/backlink.ts: 変更なしsrc/stores/wikilink.ts: 変更なしsrc/stores/createScanAction.test.ts: 変更なしTier 推定
Tier B (defect-detection 強化、impact 小〜中、scope 小)