Typescript中类型别名

在Typescript中集成了很多类型别名,而且这些类型别名功能还很强大,同时,在项目中,这些别名的使用率还是非常高的。所以,对学习这些类型别名的用途还是很必要的。

ArrayLike

// 源码实现
interface ArrayLike<T> {
    readonly length: number;
    readonly [n: number]: T;
}

这表示一个类似数组的类型。比如常见argumentsNodeList对象等。

function fn(doms: ArrayLike<HTMLElement>) {
  console.log(doms);
}

fn(document.querySelectorAll("div"));

Partial

// 源码实现
type Partial<T> = {
    [P in keyof T]?: T[P];
};

从源码实现中可以看到其将T中所有的属性名都变成可选。那么Partial表示的意思是将属性全部设置为可选。

type Person = {
  name: string,
  age: number
}

type PartialPerson = Partial<Person>;

相当于

type PartialPerson = {
  name?: string | undefined,
  age?: number | undefined
}

Required

// 源码实现
type Required<T> = {
    [P in keyof T]-?: T[P];
};

它表示所有的属性都是必选

这里面-?代表的意思是取消可选,那么就变成必选了。与之相对还有+?,就是添加可选。

type Person = {
  name?: string | undefined,
  age?: number | undefined
}

type RequiredPerson = Required<Person>;

相当于

type RequiredPerson = {
  name: string,
  age: number
}

表示将Person的属性全部都变成必须的。

Readonly

// 源码实现
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

通过readonly关键字将T中的每一个属性都设置为只读的,所以Readonly表示将属性都变为只读的,不可写入。

Pick

// 源码实现
/**
 * From T, pick a set of properties whose keys are in the union K
 */
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

源码中的K来自于T的key,那么[P in K]: T[P];就表示从T中挑选出属性K的类型作为新的类型。

type Person = {
  name: string;
  age: number;
};

type PickPerson = Pick<Person, "age">;

等价于

type PickPerson = {
  age: number;
};

可以看到这个操作会将Person中的age类型单独拎出来,Pick的作用就是如此了,在一堆类型中选中几个类型。

Record

// 源码实现
/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

K中所有类型转换成T类型。

type RecordPerson = Record<"a" | "b" | "c", number>;

相当于

type RecordPerson = {
  a: number,
  b: number,
  c: number,
};

Exclude

// 源码实现
/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

T中剔除可以赋值给U的类型。

type ExcludePerson = Exclude<'a' | 'b' | 'e' | 'f', 'a' | 'b' | 'c' | 'd'>

等价于

type ExcludePerson = 'e' | 'f';

可以看到把T中存在U中不存在的给拎出来了。

Extract

// 源码实现
/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;

它表示在T中提取同时在T中和U中出现的类型。

type ExtractPerson = Extract<'a' | 'b' | 'e' | 'f', 'a' | 'b' | 'c' | 'd'>

// 等价于
type ExtractPerson = 'a' | 'b';

Omit

// 源码实现
/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

表示在T中出现的K类型。

type Person = {
  age: number;
  name: string;
  like: object[]
};

type OmitPerson = Omit<Person, 'age'>

// 等价于
type OmitPerson = {
  name: string;
  like: object[]
};

NonNullable

// 源码实现
/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

表示去除类型中的undefinednull

type T0 = string | number | undefined;

type T1 = NonNullable<T0>

// 等价于

type T1 = string | number

Parameters

// 源码实现
/**
 * Obtain the parameters of a function type in a tuple
 */
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

表示提取函数的参数组成的参数类型。

function fn(a: number, b: string) {
  return a + b;
}

type T1 = Parameters<typeof fn>

// 等价于
type T1 = [number, string]

可以看到其将fn的参数所有类型汇聚到一起成了T1

ConstructorParameters

// 源码实现
/**
 * Obtain the parameters of a constructor function type in a tuple
 */
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

表示将构造函数的参数的参数类型汇聚到一起组成新的类型

class Person {
  constructor(name: string, age: number) {}
}

type T0 = ConstructorParameters<typeof Person>;

// 等价于
type T0 = [string, number]

ReturnType

// 源码实现
/**
 * Obtain the return type of a function type
 */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

将函数的返回值的类型当做新的类型。

InstanceType

// 源码实现
/**
 * Obtain the return type of a constructor function type
 */
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

表示获取构造函数类型的实例类型。这个直接看官方的示例吧

class C {
    x = 0;
    y = 0;
}

type T20 = InstanceType<typeof C>;  // C
type T21 = InstanceType<any>;  // any
type T22 = InstanceType<never>;  // any
type T23 = InstanceType<string>;  // Error
type T24 = InstanceType<Function>;  // Error

ThisType

// 源码实现
/**
 * Marker for contextual 'this' type
 */
interface ThisType<T> { }

源码实现非常简单,只是声明一个空的接口。这个类型是用于指定上下文对象类型的。

那该怎么用呢?

type Person = {
  name: string;
  age: number;
};

const person: ThisType<Person> = {
  getName() {
    return this.name;
  }
};

可以看见this上下文已经有了name或是age属性。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注