「TypeScript」集合

112 阅读3分钟

联合类型和交叉类型

1.交叉类型 交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

type PartialPointX = { x: number }
type PartialPointY = { y: number }

type IPoint = PartialPointX & PartialPointY

const point: IPoint = {
  x: 1,
  y: 1
}
  1. 联合类型 联合类型与交叉类型很相似,但是使用上不太相同,有时我们希望一个参数可能是多种类型
const fn = (params: string | number |) => void

type和interface的区别

1.type可以用于联合类型元组类型基本类型,interface不支持

2.interface 可以多次定义 并被视为合并所有声明成员 type 不支持

interface Point {
  x: number;
}
interface Point {
  y: number;
}

const point: Point = { x: 1, y: 2 };

3.type 能使用 in 关键字生成映射类型,但 interface 不行。

type Keys = 'name' | 'age' | 'sex'

type IPerson = {
  [key in Keys]: string
}

const person: IPerson = {
  name: 'jenson',
  age: '11',
  sex: 'male'
}

4.导出方式不同, inerface 支持同时声明,默认导出 而type必须先声明后导出

export default interface IProps {
  name: string;
}

type TProps = {name: string}
export default TProps

Omit

​Omit<T, K>​ 类型让我们可以从另一个对象类型中剔除某些属性,并创建一个新的对象类型:

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

type User = {
  name: string;
  age: number;
  sex: string;
};
type UserExSex = Omit<User, "sex">;

let u: UserExSex = {
  name: "jenson",
  age: 19,
};

keyof: 用于获取某种类型的所有键,其返回类型是联合类型

type User = {
  name: string;
  age: number;
  sex: string;
};
keyof User => 'name' | 'age' | 'sex'

K extends keyof T:

K = 'name' | 'age' | 'sex'

Pick : 从类型集合中抽取出若干想要的类型

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

type User = {
  name: string;
  age: number;
  sex: string;
};
Pick<User,'name' | 'age'>    =>    'name' | 'age'

Exclude: 从类型集合中剔除若干属性

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

type User = {
  name: string;
  age: number;
  sex: string;
};
Exclude<keyof User,'name' | 'age'>    =>    'sex'

注:Pick第一个参数是type对象,Exclude第一个参数是联合类型(keyof)

因此 Omit<User, "sex"> = Pick<User,Exclude<typeof User,'sex'>> = Pick<User,'name' | 'age'>> = 'name | age'

Partial

Partial 可以把快速把类型中的某属性变为可选的

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

const person: Person = {
  name: "jenson", // err missing age
};

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

const person: Partial<Person> = {
  name: "jenson", // ok !!
};

function的不同params

有时候同一个function会出现多组不同的参数形式,如一个add function,可以接收两个字符串或两个数字相加,而不接受一个字符串和一个数字传入。

重载

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

泛型

const add = <T extends string | number>(a: T, b: T): T => {
  return a as any + b as  any // 不断言为any会报Operator '+' cannot be applied to types 'T' and 'T'.ts(236
};

add(1, 2); // ok
add('1', '2'); // ok
add(1, '2'); // error

函数重载还可以更灵活的定制参数类型

function test(a: string, b: string): string;
function test(a: number): number;
function test(a, b) {
  return a + b;
}
test("1", "2"); // ok
test(1, 2); // ok
test(1, "2") // error

class _Array extends Array {
  constructor(...args) {
    super(...args);
  }

  _reduce(cb: (pre: number, cur: number) => number): number;
  _reduce(cb: (pre: string, cur: string) => string): string;
  _reduce(cb) {
    let arr = this,
      len = arr.length;
    if (len === 0) return 0;
    if (len === 1) return arr[0];
    let sum = arr[0];
    for (let i = 1; i < len; ++i) {
      sum = cb(sum, arr[i]);
    }
    return sum;
  }
}

泛型选传

interface IPerson<T = string> {
  age: T
}

这表示当你不传递类型时,age默认是string类型

const person: IPerson = {
  age: '20'
}

你也可以自定义类型

const person: IPerson<number> = {
  age: 20
}