TypeScript - 使用筆記 (4)

泛型-Generics

  • 在定義函式、介面或類別的時候,不預先指定具體的型別,而在使用的時候再指定型別的一種特性
  • T 用來指代任意輸入的型別
function myFn<T>(a: T, b: T): T[] {
    return [a, b]
}

// 指定類型:number
myFn<number>(1,2)

// 自動偵測類型:string
myFn('hello', 'bed')
const addUid = <T extends { name: string }>(obj: T) => {
  let uid = Math.floor(Math.random() * 100);
  return { ...obj, uid };
};

let docOne = addUid({ name: 'Claude', age: 29 });

// 用在函式參數的型別
function createPair<typeX, typeY>(x: typeX, y: typeY): [typeX, typeY] {
 return [x, y];
}
console.log(createPair<string, number>('Meaning', 42));

with interface

// data還不確定類型時,可以使用泛型
interface Resource<T> {
  uid: number;
  resourceName: string;
  data: T;
}

// 可以指定類型,例如data的值要是一個物件
const docThree: Resource<object> = {
  uid: 1,
  resourceName: 'person',
  data: { name: 'Yong' },
};

使用extends限制

  • 限定回傳的結果是number
interface Inter{
    length: number
}
function fn<T extends Inter>(input: T):number{
    return input.length
}

fn('666')
fn(123) // Argument of type 'number' is not assignable to parameter of type 'Inter'

當組合兩個數列時

function join<T>(arr1: T[], arr2: T[]): T[] {
    return [...arr1, ...arr2]
}

// 把所有的T使用string類型代入
const res = join<string>(['1', '2', '3'], ['4', '5', '6'])
res.map((x) => x.toUpperCase())

定義多個泛型參數

function printType<T, K>(t: T, k: K){
    console.log(typeof t, typeof k)
}

printType<string, number>('abc', 123)

串接API取得資料時

  • 在Nuxt3使用useFetch
  • 可以定義一個ApiResponse,在多個API請求中重複使用
  interface ApiResponse<T> {
    status: boolean
    result: T
  }
  interface User {
    name: string
    age: number
    role: string
  }

  interface Job {
    title: string,
    componany: string,
    salary: number
  }
  
  const user = ref<User | null>(null)

  const { data, error } = await useFetch<ApiResponse<User>>(`${apiBase}/user/1`)

  if (data.value) {
    user.value = data.value.result.user
  }
  if (error.value) {
    console.error(error.value)
  }

  const job = ref<Job | null>(null);

  const { data: jobData, error: jobError } = await useFetch<ApiResponse<Job>>(`${apiBase}/job`);

  if (jobData.value) {
    job.value = jobData.value.result;
  }
  if (jobError.value) {
    console.error(jobError.value);
  }

參考資料

# TypeScript