TS碰见的特殊类型收集


Pick

内置

type中选出指定属性构成新type

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

Partial

内置

type中所有属性转换为可选

type Partial<T> = {
    [P in keyof T]?: T[P];
};

Exclude排除

内置

T不继承自U就返回T

一般用于联合类型,去除T中U包含的部分(T-U,T和U的差集)

type Exclude<T, U> = T extends U ? never : T;

Extract提取

内置

T继承自U就返回T

一般用于联合类型,提取T中U包含的部分(T和U的交集)

type Extract<T, U> = T extends U ? T : never;

Omit

type中移除K属性

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

自定义条件类型——-

类型是否相同,并返回指定类型

type isEqual<T, U, Success, Fail> = [T] extends [U] ? [U] extends [T] ? Success : Fail : Fail;

除去T中的string类型以外的属性

拿到T中,string类型的key的联合类型

type Person = {
    name: string;
    age: number;
    address: string;
}
type ExtractKeysByValueType0<T, U> = {
    [K in keyof T]: isEqual< T[K], U, K, never >; // equal就要这个key,不equal就设定为never
}
// 建立映射 { name: "name"; age: never; address: "address"; }

type ExtractKeysByValueType1<T, U> = {
    [K in keyof T]: isEqual< T[K], U, K, never>
}[keyof T] // {}拿到了新的类,然后{}[]通过key拿到了值,type取属性.同时具有去掉never的作用
// "name" | "address"

除去T中的string类型以外的属性

type ExtractKeysByValueType<T, U> = Pick<T, ExtractKeysByValueType1<T, U>>
// { name: string;address: string; }

除去T中的string类型的属性

type OmitKeysByValueType1<T, U> = {
    [K in keyof T]: isEqual< T[K], U, never, K> // 反一下
}[keyof T] 
type OmitKeysByValueType<T, U> = Pick<T, OmitKeysByValueType1<T, U>>
// { age: number; }

除去T中的string类型以外的属性

type PickKeysByValue<T extends object, U> = {
  // as 语法 映射成一个新的变量
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

查看复杂类型的属性

type Compute<T extends object> = {
    [key in keyof T]: T[key];
};

T中指定K改为可选类型

type PartialPropsOptional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>

T和U类的交集

type ObjectInter<T extends object, U extends object> = Pick<
  U,
  Extract<keyof T, keyof U> // name,address
>;

T和U类的差集

// 求对象的差集  T - U . Omit+Extract == Pick + Exclude
type ObjectDiff<T extends object, U extends object> = Pick<
  U,
  Exclude<keyof T, keyof U> // name,address
>;

删除U中与T的交集(T的补集:T+属性成为U)

type ObjectComp<T extends object, U extends T> = Omit<
  U,
  Extract<keyof T, keyof U>
>;

U中和T重合的部分覆写T

type A = {
  name: string;
  age: number;
  address: string;
};

type B = {
  name: string;
  address: number;
  male: boolean;
};

// A=> {name:string,age:number,address:number}

type Overwrite<T extends object, U extends object> = ObjectInter<T, U> &
  ObjectDiff<U, T>;

type X4 = Compute<Overwrite<A, B>>;
// { name: string; address: number; age: number; }

约束类型为几种类型之一

type x = Man1 | Man2 | Man3是不行的,因为这样会允许Man1中出现Man2的属性。

要完成OrType需要将其他类型的属性置为 ?:never,不存在该属性或为never。

interface Man1 {
  fortune: string; // 有钱的男人
  // funny?: never; // 要完成的效果
}
interface Man2 {
  funny: string; // 风趣的
}
interface Man3 {
  foreign: string;
}

// U中除去T中的属性,并改为?:never
type Discard<T, U> = {
  [K in Exclude<keyof U, keyof T>]?: never;
};

// U中属性为never并上T,或 T中属性为never并上U
type OrType<T, U> = (Discard<T, U> & T) | (Discard<U, T> & U);

type ManType = OrType<Man1, OrType<Man2, Man3>>;

let type: ManType = {
  foreign: "",
  // funny: undefined,
  // ss:"" // error:不能有多余属性
};

TS内置工具类型


文章作者: 罗紫宇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗紫宇 !
  目录