91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TypeScript內置工具類型怎么使用

發布時間:2023-03-09 11:20:34 來源:億速云 閱讀:97 作者:iii 欄目:開發技術

這篇文章主要介紹“TypeScript內置工具類型怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“TypeScript內置工具類型怎么使用”文章能幫助大家解決問題。

    一、什么是ts內置工具類型

    TypeScript 附帶了大量類型,可以幫助進行一些常見的類型操作,通常稱為 Utility Types。

    二、使用示例

    1.Partial

    將必填參數變為可選參數

    namespace a {
      // 示例一:
      interface A {
        name: string,
        age: number,
        sex: string
      }
      // 接口A中的參數通過內置工具類型Partial變成了可選參數
      type PartialA = Partial<A>;
      let a: PartialA = {
        // 此處傳參可以任意個數,但只能傳已定義的參數
        name: '張三',
        age: 10
      }
      // 示例二:
      interface Company {
        id: number,
        name: string
      }
      interface Person {
        id: number,
        name: string,
        company: Company
      }
      // 實現DeepPartial,將參數深度轉換成可選參數
      type DeepPartial<T> = {
        [U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U];
      }
      type PartialPerson = DeepPartial<Person>;
      let p: PartialPerson = {
        // 此處的參數已經變為可選參數,可根據自己需要傳遞
        id: 10,
        name: '張三',
        company: {
          name: '美團'
        }
      }
    }

    Partial的實現源碼

    namespace b {
      interface A {
        name: string,
        age: number,
        sex: string
      }
      type Partial<T> = {
        // 原理:
        // 1.通過keyof拿到T中的所有key
        // 2.迭代所有的key
        // 3.統一加上可選參數處理
        // 4.返回迭代值的類型
        [P in keyof T]?: T[P];
      }
      // 測試:
      type PartialA = Partial<A>;
      let a: PartialA = {
        name: '張三',
        age: 10
      }
    }

    2.Required

    將所有參數變為必填

    namespace b {
      interface Person {
        name: string,
        age?: number
      }
      // Required將可選參數變為必填
      type RequiredPerson = Required<Person>;
      let person: RequiredPerson = {
        name: '張三',
        age: 10
      }
    }

    Required 的實現源碼

    namespace c {
      interface Person {
        name: string,
        age?: number
      }
      type Required<T> = {
        // 原理:
        // 1.通過keyof拿到T中所有的key
        // 2.迭代所有的key
        // 3.將可選的參數變為必填的參數
        // 4.返回迭代屬性及類型
        // +?或者?: 代表的是可選,-?: 代表的是不可選
        [P in keyof T]-?: T[P];
      };
      // 測試
      type RequiredPerson = Required<Person>;
      let person: RequiredPerson = {
        name: '李四',
        age: 18
      }
    }

    3.ReadOnly

    將所有參數變為只讀

    namespace d {
      interface Person {
        name: string,
        age?: number
      }
      type ReadonlyPerson = Readonly<Person>;
      let person: ReadonlyPerson = {
        name: '張三',
        age: 10
      }
      // 已經變為只讀屬性,因此此處賦值會報錯
      // person.name = '李四'; // 無法分配到 "name" ,因為它是只讀屬性。ts(2540)
      // person.age = 20; // 無法分配到 "age" ,因為它是只讀屬性。ts(2540)
    }

    Readonly 的實現源碼

    namespace e {
      interface Person {
        name: string,
        age?: number
      }
      type Readonly<T> = {
        // 原理:
        // 1.通過keyof拿到T中所有key
        // 2.迭代拿到的所有key
        // 3.通過readonly關鍵字將所有屬性變為只讀屬性
        // 4.返回迭代屬性及類型
        readonly [P in keyof T]: T[P]
      }
      // 測試
      type ReadonlyPerson = Readonly<Person>;
      let person: ReadonlyPerson = {
        name: '張三',
        age: 10
      }
      // person.name = '李四'; // 無法分配到 "name" ,因為它是只讀屬性。ts(2540)
      // person.age = 20; // 無法分配到 "age" ,因為它是只讀屬性。ts(2540)
    }

    4.Pick

    撿取符合條件的屬性

    namespace g {
      interface Person {
        name: string,
        age: number,
        sex: string
      }
      // 參數一是一個對象,參數二是要篩選的屬性
      type PickPerson = Pick<Person, 'name' | 'sex'>;
      let person: PickPerson = {
        name: '張三',
        // 由于通過Pick只撿取了name和sex屬性,因此此時給sex賦值會報錯
        // 不能將類型“{ name: string; age: number; sex: string; }”分配給類型“PickPerson”。
        // 對象文字可以只指定已知屬性,并且“age”不在類型“PickPerson”中。ts(2322)
        // age: 10,
        sex: '男'
      }
    }

    Pick 的實現源碼

    namespace h {
      interface Person {
        name: string,
        age: number,
        sex: string
      }
      // 原理:
      // 1.T表示傳入的類型定義。此處指Person接口。
      // 2.K表示T的子類型,是一個聯合類型。此處指'name' | 'age' | 'sex'的子類型
      // 3.通過keyof拿到T中的所有key
      // 3.迭代K,拿到所有傳遞進來的子類型
      // 4.返回迭代屬性及類型
      // 簡單理解:就是從一個對象中,提取一部分屬性組成新的對象
      type Pick<T, K extends keyof T> = {
        [P in K]: T[P];
      }
      // 測試
      type PickPerson = Pick<Person, 'name' | 'age'>
      let person: PickPerson = {
        name: '張三',
        age: 10
      }
    }

    5.Record

    記錄類型:將一個類型的所有屬性值都映射到另一個屬性上并創建新的類型

    namespace i {
      // 1.此處的K主要用來修飾obj對象的key,為string或者number
      // 2.此處的T用來修飾老的類型
      // 3.此處的U用來修飾新的類型
      function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) {
        // 聲明一個變量
        let result: Record<K, U> = <Record<K, U>>{};
        // 遍歷傳入的對象
        for (const key in obj) {
          // 通過callback函數處理result的屬性值
          result[key] = callable(obj[key]);
        }
        // 返回result
        return result;
      }
      let obj = { num1: 1, num2: 2 };
      let callable = (x: number): string => x * 2 + '';
      let newObj = mapObj<string | number, number, string>(obj, callable);
      console.log(newObj); // { num1: '2', num2: '4' }
    }

    Record 的實現源碼

    namespace j {
      type Record<K extends keyof any, T> = {
        // 原理:
        // 1.通過keyof拿到所有的K,是一個聯合類型。string | number | symbol
        // 2.迭代K,拿到所有的屬性
        // 3.返回迭代的屬性及類型
        // 注意:此處不能寫成 type Record<K, T> = {}; any代表所有key的聯合類型。
        // 否則會報錯:不能將類型“K”分配給類型“string | number | symbol”。ts(2322)
        [P in K]: T;
      };
      // 測試
      function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) {
        // 聲明一個變量
        let result: Record<K, U> = <Record<K, U>>{};
        // 遍歷傳入的對象
        for (const key in obj) {
          // 通過callback函數處理result的屬性值
          result[key] = callable(obj[key]);
        }
        // 返回result
        return result;
      }
      let obj = { num1: 1, num2: 2 };
      let callable = (x: number): string => x * 2 + '';
      let newObj = mapObj<string | number, number, string>(obj, callable);
      console.log(newObj); // { num1: '2', num2: '4' }
    }

    關于“TypeScript內置工具類型怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    鸡西市| 株洲市| 揭西县| 来安县| 黄梅县| 无棣县| 民县| 静安区| 丰原市| 布尔津县| 津市市| 新泰市| 东乡族自治县| 江安县| 新巴尔虎右旗| 盘锦市| 新安县| 航空| 上林县| 瑞丽市| 香河县| 徐汇区| 松潘县| 都江堰市| 道真| 手机| 土默特左旗| 三明市| 克山县| 肃宁县| 化德县| 霍林郭勒市| 临汾市| 北川| 兴文县| 通城县| 射阳县| 余庆县| 南平市| 互助| 苍山县|