🎯 引数の型が間違ったらエラーになる設計(Vuex × TypeScript 完全型安全設計)

【第5章 続き】

🎯 引数の型が間違ったらエラーになる設計(Vuex × TypeScript 完全型安全設計)


🟢 要点まとめ


🥕 たとえ:注文票の「メニュー番号と注文内容」

「3番のピザ」には「枚数」を書く必要がある。

「4番のパスタ」には「ソースの種類」が必要。

メニュー番号と内容がバラバラだったら怒られる。

それが 型安全なpayload設計


📦 型設計(types.ts

// RootState
export interface RootState {
  count: number;
  userName: string;
}

// mutation名
export const MutationTypes = {
  Increment: 'increment',
  SetUserName: 'setUserName'
} as const;
export type MutationType = typeof MutationTypes[keyof typeof MutationTypes];

// action名
export const ActionTypes = {
  UpdateUserName: 'updateUserName'
} as const;
export type ActionType = typeof ActionTypes[keyof typeof ActionTypes];

// mutation payloads(引数の型)
export interface MutationPayloads {
  [MutationTypes.Increment]: undefined;        // incrementは引数なし
  [MutationTypes.SetUserName]: string;         // setUserNameはstring型
}

// action payloads(引数の型)
export interface ActionPayloads {
  [ActionTypes.UpdateUserName]: string;        // updateUserNameはstring型
}

// action returns(戻り値の型)
export interface ActionReturns {
  [ActionTypes.UpdateUserName]: boolean;       // 戻り値はboolean
}


🟠 型付き commitTyped 実装

import { Store } from 'vuex';
import { RootState, MutationType, MutationPayloads } from './types';

// 型付きcommit
export const commitTyped = <
  T extends MutationType
>(
  store: Store<RootState>,
  type: T,
  payload: MutationPayloads[T]
): void => {
  store.commit(type, payload);
};

✅ ここで MutationPayloads[T] によって

increment には undefined しか渡せない