交叉类型

  • 交叉类型(Intersection Types)是将多个类型合并为一个类型
  • 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性 ```typescript interface Bird { name: string fly(): void } interface Person { name: string talk(): void } type BirdPerson = Bird & Person let p: BirdPerson = { name: ‘lc’, fly() {}, talk() {} } p.fly p.name p.talk
  1. <a name="eXsSD"></a>
  2. ### 联合类型的交叉类型
  3. ```typescript
  4. type Ta = string | number
  5. type Tb = number | boolean
  6. type Tc = Ta & Tb // number

mixin

mixin混入模式可以让你从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能

  1. interface AnyObject {
  2. [prop: string]: any
  3. }
  4. function mixin<T extends AnyObject, U extends AnyObject>(
  5. one: T,
  6. two: U,
  7. ): T & U {
  8. const result = <T & U>{}
  9. for (let key in one) {
  10. ;(<T>result)[key] = one[key]
  11. }
  12. for (let key in two) {
  13. ;(<U>result)[key] = two[key]
  14. }
  15. return result
  16. }
  17. const x = mixin({ name: 'lc' }, { age: 18 })
  18. console.log(x.name, x.age)

keyof

  • 索引类型查询操作符 ```typescript interface Person { name: string age: number gender: ‘male’ | ‘female’ } //type PersonKey = ‘name’|’age’|’gender’; type PersonKey = keyof Person // 得到字面量类型

function getValueByKey(p: Person, key: PersonKey) { return p[key] } let val = getValueByKey({ name: ‘lc’, age: 18, gender: ‘male’ }, ‘name’) console.log(val)

  1. <a name="o4jlY"></a>
  2. ## 条件类型
  3. <a name="KZhMn"></a>
  4. ### 定义条件类型
  5. ```typescript
  6. interface Fish {
  7. name: string
  8. }
  9. interface Water {
  10. name: string
  11. }
  12. interface Bird {
  13. name: string
  14. }
  15. interface Sky {
  16. name: string
  17. }
  18. //若 T 能够赋值给 Fish,那么类型是 Water,否则为 Sky
  19. type Condition<T> = T extends Fish ? Water : Sky
  20. let condition: Condition<Fish> = { name: '水' }
  • 找出T类型中U不包含的部分 ```typescript //never会被自动过滤 type Diff = T extends U ? never : T

type R = Diff<’a’ | ‘b’ | ‘c’ | ‘d’, ‘a’ | ‘c’ | ‘f’> // “b” | “d”

type Filter = T extends U ? T : never type R1 = Filter

  1. <a name="p59J9"></a>
  2. ### 内置条件类型
  3. <a name="jW0k6"></a>
  4. ##### Exclude
  5. - 从 T 可分配给的类型中排除 U
  6. ```typescript
  7. // type Exclude<T, U> = T extends U ? never : T
  8. type E = Exclude<string | number, string> // 排除string类型
  9. let e: E = 10

Extract
  • 从 T 可分配的类型中提取 U ```typescript // type Extract = T extends U ? T : never

type E = Extract // 可以理解为交集 let e: E = ‘1’

  1. <a name="IGkGo"></a>
  2. ##### NonNullable
  3. ```typescript
  4. // type NonNullable<T> = T extends null | undefined ? never : T
  5. type E = NonNullable<string | number | null | undefined>
  6. let e: E = null

ReturnType
  • infer最早出现在此 PR 中,表示在 extends 条件语句中待推断的类型变量
  • 获取函数类型的返回类型 ```typescript type ReturnType any> = T extends ( …args: any[] ) => infer R ? R : any

function getUserInfo() { return { name: ‘lc’, age: 18 } }

// 通过 ReturnType 将 getUserInfo 的返回值类型赋给了 UserInfo type UserInfo = ReturnType / type UserInfo = { name: string; age: number; } / const userA: UserInfo = { name: ‘lc’, age: 18, }

  1. <a name="oOdZj"></a>
  2. ## 内置工具类型
  3. <a name="QLPNK"></a>
  4. ### Partial 可选转换
  5. Partial 可以将传入的属性由非可选变为可选
  6. ```typescript
  7. interface A {
  8. a1: string
  9. a2: number
  10. a3: boolean
  11. }
  12. type aPartial = Partial<A>
  13. const a: aPartial = {} // 不会报错

原理

  1. type Partial<T> = { [P in keyof T]?: T[P] }
  2. // in 可以理解为 for ... in,表示从 keyof T 中去遍历每一个类型

用js伪代码模拟

  1. const newType = {}
  2. Object.keys(T).forEach(key => {
  3. newType[key] = !T[key]
  4. })

其他类似的还有

  • Required 必选转换
  • Readonly 只读转换

    DeepPartial 类型递归

    将递归类型展开 ```typescript interface Company { id: number name: string }

interface Person { id: number name: string company: Company } type R2 = DeepPartial

  1. 原理
  2. ```typescript
  3. type DeepPartial<T> = {
  4. [U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U]
  5. }

Pick

  • Pick 能够帮助我们从传入的属性中摘取某一项或多项返回 ```typescript /**
    • From T pick a set of properties K
    • type Pick = { [P in K]: T[P] }; */ // 摘取 Person 中的 name 和 age 属性 interface Person { name: string age: number married: boolean }

let person: Person = { name: ‘lc’, age: 18, married: false } let result: Pick = { name: ‘lc’, age: 18, } console.log(result)

  1. <a name="WpJed"></a>
  2. ### Record
  3. - Record 是 TypeScript 的一个高级类型
  4. - 他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型
  5. ```typescript
  6. /**
  7. * Construct a type with a set of properties K of type T
  8. */
  9. type Record<K extends keyof any, T> = {
  10. [P in K]: T;
  11. };
  1. type Point = 'x' | 'y'
  2. type PointList = Record<Point, { value: number }>
  3. type PointList = {
  4. x: {
  5. value: number;
  6. };
  7. y: {
  8. value: number;
  9. };
  10. }