交叉类型
- 交叉类型(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
<a name="eXsSD"></a>### 联合类型的交叉类型```typescripttype Ta = string | numbertype Tb = number | booleantype Tc = Ta & Tb // number
mixin
mixin混入模式可以让你从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能
interface AnyObject {[prop: string]: any}function mixin<T extends AnyObject, U extends AnyObject>(one: T,two: U,): T & U {const result = <T & U>{}for (let key in one) {;(<T>result)[key] = one[key]}for (let key in two) {;(<U>result)[key] = two[key]}return result}const x = mixin({ name: 'lc' }, { age: 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)
<a name="o4jlY"></a>## 条件类型<a name="KZhMn"></a>### 定义条件类型```typescriptinterface Fish {name: string}interface Water {name: string}interface Bird {name: string}interface Sky {name: string}//若 T 能够赋值给 Fish,那么类型是 Water,否则为 Skytype Condition<T> = T extends Fish ? Water : Skylet 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
<a name="p59J9"></a>### 内置条件类型<a name="jW0k6"></a>##### Exclude- 从 T 可分配给的类型中排除 U```typescript// type Exclude<T, U> = T extends U ? never : Ttype E = Exclude<string | number, string> // 排除string类型let e: E = 10
Extract
- 从 T 可分配的类型中提取 U
```typescript
// type Extract
= T extends U ? T : never
type E = Extract
<a name="IGkGo"></a>##### NonNullable```typescript// type NonNullable<T> = T extends null | undefined ? never : Ttype E = NonNullable<string | number | null | undefined>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
<a name="oOdZj"></a>## 内置工具类型<a name="QLPNK"></a>### Partial 可选转换Partial 可以将传入的属性由非可选变为可选```typescriptinterface A {a1: stringa2: numbera3: boolean}type aPartial = Partial<A>const a: aPartial = {} // 不会报错
原理
type Partial<T> = { [P in keyof T]?: T[P] }// in 可以理解为 for ... in,表示从 keyof T 中去遍历每一个类型
用js伪代码模拟
const newType = {}Object.keys(T).forEach(key => {newType[key] = !T[key]})
其他类似的还有
- Required 必选转换
- Readonly 只读转换
DeepPartial 类型递归
将递归类型展开 ```typescript interface Company { id: number name: string }
interface Person {
id: number
name: string
company: Company
}
type R2 = DeepPartial
原理```typescripttype DeepPartial<T> = {[U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U]}
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
<a name="WpJed"></a>### Record- Record 是 TypeScript 的一个高级类型- 他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型```typescript/*** Construct a type with a set of properties K of type T*/type Record<K extends keyof any, T> = {[P in K]: T;};
type Point = 'x' | 'y'type PointList = Record<Point, { value: number }>type PointList = {x: {value: number;};y: {value: number;};}
