Skip to content

TypeScript

基础

any, unknown, never

  1. any 放弃类型检查。
ts
let vAny: any = 'Hello World!' 
vAny = 18 // ok! ts不会管any的类型检查
vAny = true // ok! ts不会管any的类型检查
  1. unknown 允许你指定一个未知的类型。在后续的类型分流中,类型会逐渐收窄,最终得到一个更精确的类型。
ts
/** 例1 */
let vAny: any = 'Hello World!'
let vUnknown: unknown = 'Hello World!'

let vNumberForAny: number = vAny // ok! any可以直接赋值给其它任意类型
let vNumberForUnknown: number = vUnknown // error! unknown不可以直接赋值给其它非any和unknown类型的对象

/** 例2 */
let vUnknown: unknown = 'abc'

// 使用typeof推断出vUnknown的类型是string
if (typeof vUnknown === 'string') {
    vUnknown.toLocaleUpperCase() // ok! 因为能进入这个if条件体就证明了vUnknown是字符串类型!
}

let vNumberForUnknown: number = vUnknown as number // unknown类型一定要使用as关键字转换为number才可以赋值给number类型
  1. never 表示一个不会出现的类型。例如一个函数抛出错误,那么never就是这个函数的返回值类型。
ts
/** 例1 */
function crashFunc(): never {
  throw new Error('this function will crash')
}

/** 例2 */
type Texample = string & number // never, 因为一个类型不可能即是string,也是number

交叉类型

交叉类型是一种将多种类型组合为一种类型的方法。 这意味着你可以将给定的类型 A 与类型 B 或更多类型合并,并获得具有所有属性的单个类型。

ts
interface Colorful {
  color: string;
}
interface Circle {
  radius: number;
}
 
type ColorfulCircle = Colorful & Circle;
// {
//   color: string;
//   radius: number;
// }

function draw(circle: Colorful & Circle) {
  console.log(`Color was ${circle.color}`);
  console.log(`Radius was ${circle.radius}`);
}

draw({ color: "blue", radius: 42 });
// Output: { color: "blue", radius: 42 }

联合类型

联合类型是由两种或多种其他类型组成的类型,表示可能是这些类型中的任何一种的值。

ts
type UnionType = string | number;

function showType(arg: UnionType) {
    console.log(arg);
}

showType("test");
// Output: test

showType(7);
// Output: 7

泛型

泛型指的是在定义函数/接口/类型时,不预先指定具体的类型,而是在使用的时候在指定类型限制的一种特性。

ts
/** 联合类型中使用 */
type UnionType<T> = T | string | number;

const example1: UnionType<boolean> = true; // 正确
// boolean | string | number;

/** 接口中使用 */
interface Container<T> {
    data: T;
}

const container1: Container<number> = { data: 10 };
// {
//   data: number;
// }
const container2: Container<string> = { data: "hello" };
// {
//   data: string;
// }

infer 关键字

在条件类型中提取类型的某一部分信息

ts
// 提取函数的返回值类型
type FunctionReturnType<T extends Func> = T extends (
  ...args: any[]
) => infer R
  ? R
  : never;

内置工具

Partial<Type>

接收一个对象类型,并将这个对象类型的所有属性都标记为可选的。

ts
interface User {
  name: string;
  age: number;
}

type PartialUser = Partial<User>;
// {
//   name?: string;
//   age?: number;
// }

实现:

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

Required<Type>

接收一个对象类型,并将这个对象类型的所有属性都标记为必选的。

ts
interface User {
  name?: string;
  age?: number;
}

type RequiredUser = Required<User>;
// {
//   name: string;
//   age: number;
// }

实现:

ts
type Required<T> = {
    [P in keyof T]-?: T[P];
};

Readonly<Type>

接收一个对象类型,并将这个对象类型标记为只读的。

ts
interface User {
  name: string;
  age: number;
}

type ReadonlyUser = Readonly<User>;

const readonlyUser: ReadonlyUser = {
  name: "test",
  age: 18
}

readonlyUser.name = "test2"; // Error

实现:

ts
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

Pick<Type, Keys>

接收一个对象类型,以及一个字面量类型组成的联合类型,这个联合类型只能是由对象类型的属性名组成的。它会从传入的对象类型中,提取出指定的联合类型,并返回一个新的对象类型。

ts
interface User {
  name: string;
  age: number;
}

type PickUserName = Pick<User, "name">;
// {
//   name: string;
// }

实现:

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

Omit<Type, Keys>

Pick相反,Omit会从传入的对象类型中,删除指定的联合类型,并返回一个新的对象类型。

ts
interface User {
  name: string;
  age: number;
}

type OmitUserName = Omit<User, "name">;
// {
//   age: number;
// }

实现:

ts
type Omit<T, K> = {
    [P in Exclude<keyof T, K>]: T[P];
};

Record<Keys Type>

用于构造一个对象类型,它所有的key(键)都是Keys类型,它所有的value(值)都是Type类型。这个工具类型可以被用于映射一个类型的属性到另一个类型。

ts
interface UserInfo {
  name: string;
  age: number;
}

type UserName = "zhangshan" | "lisi" | "wangwu";

const users: Record<UserName, UserInfo> = {
  zhangshan: { name: "zhangshan", age: 10 },
  lisi: { name: "lisi", age: 10 },
  wangwu: { name: "wangwu", age: 10 }
};

实现:

ts
type Record<K, T> = {
    [P in K]: T;
};

Extract<Type, Union>

Type联合类型中提取Union类型中也存在的部分,即交集

ts
type UserProps = "name" | "age" | "email";
type RequiredUserProps = "name" | "age";

type OptionalUserProps = Extract<UserProps, RequiredUserProps>;

const optionalUserProps: OptionalUserProps = "name"; // "name" | "age"

实现:

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

Exclude<UnionType, ExcludedMembers>

UnionType联合类型中移除所有的ExcludedMembers的类型,即差集

ts
type UserProps = "name" | "age" | "email";
type RequiredUserProps = "name" | "age";

type OptionalUserProps = Exclude<UserProps, RequiredUserProps>;

const optionalUserProps: OptionalUserProps = "email"; // "email"

实现:

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

NonNullable<Type>

Type中排除了所有的null、undefined的类型。

ts
type T0 = NonNullable<string | number | undefined>; // string | number

type T1 = NonNullable<string[] | null | undefined>; // string[]

实现:

ts
type NonNullable<T> = T & {}; // 泛型参数T和{}的交集就默认排除了`null` 和 `undefined`

Parameters<Type>

提取函数的参数类型

ts
const addHandler = (x: number, y: number) => x + y;

type Add = typeof addHandler; // (x: number, y: number) => number;

type AddParams = Parameters<Add>; // [number, number]

实现:

ts
type Parameters<T> = T extends (...args: infer Args) => any ? Args : never;

ReturnType<Type>

提取函数的返回值类型

ts
const addHandler = (x: number, y: number) => x + y;

type Add = typeof addHandler; // (x: number, y: number) => number;

type AddParams = ReturnType<Add>; // number

实现:

ts
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;

Released under the MIT License.

本站访客数 152 人次 本站总访问量 224