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