iT邦幫忙

1

前端金三角 (3):TypeScript 皇家衛兵 —— 打造堅不可摧的數據流

  • 分享至 

  • xImage
  •  

什麼是 TypeScript ?

定義好規格的型別說明書,在開發階段針對型別幫我抓錯,編譯成純 JavaScript,執行在任何瀏覽器上。(但編譯後無法抓出錯誤型別XD)

現在 Pinia 和 TypeScript 如何相互配合?

  1. /src/api/services/activity.ts 建立 api router

    import { CreateActivityFilter, ActivityListResponse } from '../types/activity';
    
    export const getActivityList = (data: **CreateActivityFilter**) =>
      // <ActivityListResponse> 確保了 res.data 的型別
      http.post<**ActivityListResponse**>(`/activity/list`, data);
    
  2. params 和 response types 都得要在 /src/api/types/activity.ts 建立輸入和輸出的型別,確保資料長得正確

    // api/services 中要傳送的 payload
    export type **CreateActivityFilter** = {
      category?: string[];
      keyword: string;
      page: number;
    }
    
    // 單一活動的詳細內容格式
    export type **ActivityItem** = {
      id: string;
      title: string;
      date: string;
      isActive: boolean;
    }
    
    // api/services 中該 function 得到的 response
    export type **ActivityListResponse** = {
      activities: **ActivityItem**[]; // 裡面裝著活動項目的陣列
      totalCount: number;
    }
    
    
  3. /src/stores/activity.ts 將 API 抓回來的資料交給 Pinia 管理,並自動補全型態

    import { defineStore } from 'pinia';
    import { getActivityList } from '@/api/services/activity';
    import { ActivityItem, CreateActivityFilter } from '@/api/types/activity';
    
    export const useActivityStore = defineStore('activity', {
      state: () => ({
        // 使用 "as" 斷言,告訴 TS 這是一個 ActivityItem 型別的陣列
        list: [] as ActivityItem[],
        loading: false
      }),
    
      actions: {
        // 這裡可以接收參數,並傳給 API service
        async fetchActivityList(filter: CreateActivityFilter) {
          this.loading = true;
          try {
            const res = await getActivityList(filter);
            // 因為 API service 已經定義了 Response 型別
            // 這裡的 res.activities 會被 TS 自動識別為 ActivityItem[]
            this.list = res.activities; // this 可以直接拿到資料,因為都在同一個物件實例上
            return res;
        } catch (err) {
          return err;
        }
        }
      }
    });
    
  4. 在檔案下呼叫該 api

    // 利用 store 儲存的 state 取資料
    const activityStore = useActivityStore(); 
    
    try {
        // 呼叫時,TS 會強迫你傳入符合 CreateActivityFilter 格式的物件
        await activityStore.fetchActivityList({
          keyword: '',
          page: 1,
          category: ['運動', '講座']
        });
      } catch (error) {
        // 處理錯誤邏輯
      }
    

以上整理完畢,從Vuex Store 進化到 Pinia 搭配 TypeScript 的流程,希望之後別再忘記了!


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言