Proxy & Reflect
- 概念
- Proxy
- es6新增的一個對象攔截器,類似es5的defineProperty。
- 可以監(jiān)聽到一個對象的變化,取值和設置值,vue3也是通過proxy做的屬性的劫持
- Reflect
- 配合Proxy用來操作對象
- Proxy
- 例子
type Person1 = { name: string age: number sex: string } const proxy = (obj: any, key: any) => { return new Proxy(obj, { get(target, prop, receiver) { console.log('get', prop) return Reflect.get(target, prop, receiver) }, set(target, prop, value, receiver) { console.log('set', prop) return Reflect.set(target, prop, value, receiver) }, }) } // 固定的太死了 const log1 = (obj: Person1, key: 'name' | 'age' | 'sex') => { return proxy(obj, key) } let ps1: Person1 = log1( { name: '亞索', age: 18, sex: '男', }, 'name' ) ps1.name = '瑞雯' ps1.sex console.log(ps1) // 優(yōu)化后 const log2 = <T>(obj: T, key: keyof T): T => { return proxy(obj, key) } let ps2 = log2( { name: '盲僧', age: 20, sex: '男', like: 'hs', }, 'like' ) ps2.like
Partial & Pick
- 內置高級類型Partial Pick
- Partial
type Person1 = { name: string; age: number; msg: string; }; type p = Partial<Person1>;
- 源碼
type Partial<T> = { [P in keyof T]?: T[P] }
- keyof 什么意思
- keyof 之后所有的key 都會變成這樣 類似 for in
- type key = 'name' | 'age' | 'msg';
- Pick
- 選取指定一組屬性滥搭,返回一個新的類型定義
type Person1 = { name: string; age: number; msg: string; }; type p = Pick<Person, 'name'>
- 源碼
type Pick<T, K extends keyof T> = { [P in K]: T[P] }
- K extends keyof T 什么意思呢
- K 我們這傳了個聯(lián)合類型 通過 extends約束了下 你只能傳你的約束的那些值 type key = 'name' | 'age' | 'msg'
type p = Pick<Person, 'xxxx'> // error
Record & Readonly
- Readonly
- 類似 Partial
- 例子
type Person1 = { name: string age: number msg: string } type p1 = Readonly<Person1> // p1 會變成這樣 // type p1 = { // readonly name: string; // readonly age: number; // readonly msg: string; // }
- 源碼
- 也是通過 keyof 把key變成聯(lián)合類型 type key = 'name' | 'age' | 'msg';
- 然后通過in 遍歷 給每個key 前面添加 readonly
- Record
- 例子
- 用來約束key栽惶,有兩個參數(shù)
type Person1 = { name: string age: number msg: string } type K = 'A' | 'B' | 'C' type p1 = Record<K, Person1> // 使用 let obj3: p1 = { A: { name: '亞索', age: 18, msg: '嘻嘻' }, B: { name: '亞索', age: 18, msg: '嘻嘻' }, C: { name: '亞索', age: 18, msg: '嘻嘻' }, }
- 源碼
type Record<K extends keyof any, T> = { [P in K]: T }
// keyof any 什么意思冕象? type key = string | number | symbol
- 例子
infer
- 基礎用法
- 新增的關鍵字充當占位符
- 例子
- 需求:定義一個類型 如果是數(shù)組類型 就返回 數(shù)組元素的類型 否則 就傳入什么類型 就返回什么類型
- 以前可能會這么寫
type Type<T> = T extends Array<any> ? T[number] : T type T1 = Type<(number | string)[]> type T2 = Type<boolean>
- 使用infer
type Type<T> = T extends Array<infer U> ? U : T type T1 = Type<(number | string)[]> type T2 = Type<boolean>
- 也可以約束成 never
// 只能傳聯(lián)合類型 不滿足 就返回 never type Type<T> = T extends Array<infer U> ? U : never type T1 = [string, number] // [string, number] type T2 = Type<boolean> // never
- 類型提取
- 提取頭部元素
type First<T extends any[]> = T extends [infer one, ...any[]] ? one : [] type T1 = First<Arrs> // type a = "a"
- 提取尾部元素
type Last<T extends any[]> = T extends [...any[], infer Last] ? Last : [] type T2 = Last<Arrs> // type b = "c"
- 刪除頭部元素
type Shift<T extends any[]> = T extends [unknown, ...infer Rest] ? Rest : [] type T3 = Shift<Arrs> // type T3 = type T3 = ["b", "c"]
- 刪除尾部元素
type Pop<T extends any[]> = T extends [...infer Rest, unknown] ? Rest : [] type T4 = Pop<Arrs> // type T4 = ["a", "b"]
- 提取頭部元素
- 遞歸
- 需求
// 需求 Arr1 正常排序 變成 Arr2 那樣 type Arr1 = [6, 5, 4, 3, 2, 1] type Arr2 = [1, 2, 3, 4, 5, 6]
- 思路
- 使用泛型約束 只能傳數(shù)組類型
- 然后提取第一個放入末尾, 循環(huán)操作 形成遞歸 滿足條件 返回
- 例子
type ReveArr<T extends any[]> = T extends [infer First, ...infer rest] ? [...ReveArr<rest>, First] : T type Result = ReveArr<Arr1> // type Result = [1, 2, 3, 4, 5, 6]
- 需求