March 18, 2025

TS infer 推斷型別


[筆記] TS infer 推斷型別

🌋 練習 1 : 完整 Return<T> 完整取的泛型內的函數返回值 (類似 ReturnType)

type sum = (a: number, b: number) => number;
type concat = (a: any[], b: any[]) => any[];

let sumResult = Return<sum>; // number
let concatResult = Return<concat>; // any[]
// type Return<T> = T 是一個函數 ? 函數的返回類型 : T
type Return<T> = T extends (...args: any[]) => infer R ? R : T;

🌋 練習 2 : 完整 PromiseType

type pt = PromiseType<string>; // string
// type PromiseType<T> = T 是一個 Promise<泛型為 K> ? Promise 帶的 K : T
type PromiseType<T> = T extends Promise<infer K> ? K : T;

如果 pt 多層泛型則遞迴 K 去多層深挖

// type PromiseType<T> = T 是一個 Promise<泛型為 K> ? Promise 帶的 K : T
type PromiseType<T> = T extends Promise<infer K> ? PromiseType<K> : T;

type pt = PromiseType<<PromiseType<string>>>; // string

🌋 練習 3 : 獲取函數第一個參數推斷型別

狀況類似練習 1, 只是利用 剩餘參數的特性 去做參數分離

type FirstArg<T> = T extends (first: infer K, ...args: any[]) : any ? K : T

type fa = FirstArg<(name: string, age: number) => void>;

🌋 練習 4 : 或許陣列泛型內的型別

T 必須是個陣列, 什麼陣列? 請 infer 幫我推斷 然後拿取推斷出來的型別當作 T, 否則不是 陣列就返回 T 類型

type ArrayType<T> = T extends (infer K)[] ? K : T;

type ItemType1 = ArrayType<[string, number]>; // string | number
type ItemType1 = ArrayType<string[]>; // string
// string[] => [string, string, ...]

其他: 函數表達式可表達形式

interface GenericFunction<T, U, R> {
  (arg1: T, arg2: U): R;
}

interface MyFunction {
  (a: number, b: string): boolean;
}

type MyFunction = (a: number, b: string) => boolean;