溫馨提示×

溫馨提示×

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

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

TypeScript內(nèi)置工具類型怎么使用

發(fā)布時間:2023-03-09 11:20:34 來源:億速云 閱讀:87 作者:iii 欄目:開發(fā)技術(shù)

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

    一、什么是ts內(nèi)置工具類型

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

    二、使用示例

    1.Partial

    將必填參數(shù)變?yōu)榭蛇x參數(shù)

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

    Partial的實現(xiàn)源碼

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

    2.Required

    將所有參數(shù)變?yōu)楸靥?/p>

    namespace b {
      interface Person {
        name: string,
        age?: number
      }
      // Required將可選參數(shù)變?yōu)楸靥?
      type RequiredPerson = Required<Person>;
      let person: RequiredPerson = {
        name: '張三',
        age: 10
      }
    }

    Required 的實現(xiàn)源碼

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

    3.ReadOnly

    將所有參數(shù)變?yōu)橹蛔x

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

    Readonly 的實現(xiàn)源碼

    namespace e {
      interface Person {
        name: string,
        age?: number
      }
      type Readonly<T> = {
        // 原理:
        // 1.通過keyof拿到T中所有key
        // 2.迭代拿到的所有key
        // 3.通過readonly關(guān)鍵字將所有屬性變?yōu)橹蛔x屬性
        // 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
      }
      // 參數(shù)一是一個對象,參數(shù)二是要篩選的屬性
      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 的實現(xiàn)源碼

    namespace h {
      interface Person {
        name: string,
        age: number,
        sex: string
      }
      // 原理:
      // 1.T表示傳入的類型定義。此處指Person接口。
      // 2.K表示T的子類型,是一個聯(lián)合類型。此處指'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

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

    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函數(shù)處理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 的實現(xiàn)源碼

    namespace j {
      type Record<K extends keyof any, T> = {
        // 原理:
        // 1.通過keyof拿到所有的K,是一個聯(lián)合類型。string | number | symbol
        // 2.迭代K,拿到所有的屬性
        // 3.返回迭代的屬性及類型
        // 注意:此處不能寫成 type Record<K, T> = {}; any代表所有key的聯(lián)合類型。
        // 否則會報錯:不能將類型“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函數(shù)處理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' }
    }

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

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI