TS 泛型变形计

56 阅读1分钟

用ts指定的语法,用编程思想对类型进行加工

函数化使用

//传入参数使用
function fun(a) {return a } 
type Partial<T> = { [P in keyof T] : T[P] } // T 相当于入参
//对参数做类型约束
function double(arg:number) {} 
type Index<T extends any[]> = (arr:T) => number  // 使用extends对范性的参数做约束
//使用默认值
function func(a:number,b:number = a ) {}
type Default <PB extends PA , PA extends number = number> = [PA,PB] // 也可以入参作为约束

控制流 & 推断

//使用控制流
const a = isTrue ? true : false 
type Type = (SomeType extends OtherType) ? TrueType : FalseType
type NonNillable<T> = T extends null | undefined ? never : T; 
type ToArray<Type> = Type extends any ? Type[] : never; // never不是any的子类
//使用参数推断
type ReverseType<T> = T extends (...args: infer Params) => infer Return ? 
Return => Params : never //若T是函数类型,则将参数和返回值的类型调换

循环

keyof : 对象上的公告属性名的联合

interface Person {
    name: string;
    age: number;
}

let personProps: keyof Person; // 'name' | 'age'
type T0 = Permon["name"] = string 

in : 遍历一些联合类型(映射)

type Keys = 'foo'|'bar'
type Flags = { [K in keys]: boolean }
// type Flags = {
//    foo: boolean;
//    bar: boolean;
//}

对象名重映射.in keyof ( TS 4.1 以上版本能够对 in keyof 遍历出来的类型再使用 as 映射 )

type excludeFooField<T> = {
    [K in keyof T as Exclude<K,"foo">] : T[K]
}
//const obj = {
//    ["name"] : T["otherName"]
//}

配合控制流

type NonNull<T> = { 
    [ K in keyof T as Exclude<K,"foo">] : T[K] extends null | undefined ? never : T[K]
}

元组

可变元组能够使用 ... 展开,且用T表示

Type arr = readonly any[];
function concat<T extends Arr, U extends Arr> ( arr1:T,arr2:U ) : [ ...T ,...U ] {
return [...arr1,...arr2] } 

标签元组 ( 解决参数名丢失)

declare function foo(...args: [string, number]): void;
declare function foo(arg0: string, arg1: number): void;

declare function bar(...args: [a: string, b: number]): void;
declare function bar(a: string, b: number): void;

递归

// [[number], [[string], boolean], object] -> [number, string, boolean, object]
export type Flatten<T extends any[]> = T extends [infer F, ...infer R]
    ? F extends any[]
        ? Flatten<[...F, ...R]>
        : [F, ...Flatten<R>]
    : [];