ts-18 进阶用法

Proxy & Reflect

  • 概念
    • Proxy
      • es6新增的一个对象拦截器,类似es5的defineProperty。
      • 可以监听到一个对象的变化,取值和设置值,vue3也是通过proxy做的属性的劫持
    • Reflect
      • 配合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)
      
        // 优化后
        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 我们这传了个联合类型 通过 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变成联合类型 type key = 'name' | 'age' | 'msg';
      • 然后通过in 遍历 给每个key 前面添加 readonly
  • Record
    • 例子
      • 用来约束key,有两个参数
      •   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

  • 基础用法
    • 新增的关键字充当占位符
    • 例子
      • 需求:定义一个类型 如果是数组类型 就返回 数组元素的类型 否则 就传入什么类型 就返回什么类型
      • 以前可能会这么写
        •  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
        •  // 只能传联合类型 不满足 就返回 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]
        
    • 思路
      • 使用泛型约束 只能传数组类型
      • 然后提取第一个放入末尾, 循环操作 形成递归 满足条件 返回
    • 例子
      •   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]
        
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容