1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        TypeScript高級特性

        共 6785字,需瀏覽 14分鐘

         ·

        2021-02-06 05:04

        關(guān)注公眾號?前端人,回復(fù)“加群

        添加無廣告學(xué)習(xí)群


        Partial & Required

        • Partial?譯為 部分的/局部的/不完全的, 作用是將一個接口的所有參數(shù)變?yōu)榉潜靥?/section>
        • Required?譯為必須的, 作用是將一個接口中所有非必填參數(shù) 變?yōu)楸靥睿?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;max-width: 100%;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.047);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);box-sizing: border-box !important;overflow-wrap: break-word !important;">Required?的作用就是將某個類型里的屬性全部變?yōu)楸剡x項。

        ts中的聲明

        /**
        ?*?Make?all?properties?in?T?optional
        ?*/

        type?Partial?=?{
        ??[P?in?keyof?T]?:?T[P];
        };

        /**
        ?*?Make?all?properties?in?T?required
        ?*/

        type?Required?=?{
        ????[P?in?keyof?T]-?:?T[P];
        };

        Partial用法示例

        type?Person?=?{
        ??name:?string;
        ??age:?number;
        }

        //?直接使用初始化所有參數(shù)都是必填
        let?tom:Person?=?{
        ????name:?'tom',
        ????age:?20
        };


        //?使用Partial將Person中所有的參數(shù)變?yōu)榉潜靥?/span>
        type?PartialPerson?=?Partial;

        let?partialPerson:?PartialPerson?=?{
        ??name:?'tom'
        };

        特殊的情況

        type?Person?=?{
        ??name:?string;
        ??age:?number;
        ??contact:?{
        ????email:?string;
        ????phone:?number;
        ????wechat:?string;
        ??}
        }

        type?PartialPerson?=?Partial;

        //?可以看出來?第一層屬性都變成了非必填??第二層都沒變
        let?partialPerson:?PartialPerson?=?{
        ??name:?'tom',
        ??contact:?{?//?error
        ????email:?'[email protected]'
        ??}
        };


        //?再來看看ts內(nèi)部類型的定義
        /**
        ?*?Make?all?properties?in?T?optional
        ?*/

        type?Partial?=?{
        ????[P?in?keyof?T]?:?T[P];
        };
        //?可以看出來并沒有考慮內(nèi)層


        //?稍微改造一下
        /**
        ?*?Make?all?properties?in?T?optional
        ?*/

        type?DeepPartial?=?{
        ??[P?in?keyof?T]?:?T[P]?extends?Object???DeepPartial?:?T[P];
        }

        //?現(xiàn)在針對那種特殊情況就能處理了

        Required 用法示例

        interface?User?{
        ??id:?number;
        ??age:?number;
        }
        type?PartialUser?=?Partial;
        //?type?PartialUser?=?{
        //?????id?:?number;
        //?????age?:?number;
        //?}
        type?PickUser?=?Required;
        //?type?PickUser?=?{
        //?????id:?number;
        //?????age:?number;
        //?}

        Record

        Record?譯為 記錄/記載, 作用是將一個類型的所有屬性值都映射到另一個類型上并創(chuàng)造一個新的類型

        ts中的聲明

        /**
        ?*?Construct?a?type?with?a?set?of?properties?K?of?type?T
        ?*/

        type?Record?=?{
        ????[P?in?K]:?T;
        };

        看類型的定義就可以看出來,將K中的每個屬性([P in K]),都轉(zhuǎn)為T類型, K可以是聯(lián)合類型、對象、枚舉…

        type?petsGroup?=?'dog'?|?'cat'?|?'fish';

        type?numOrStr?=?number?|?string;

        type?IPets?=?Record;

        //?type?IPets?=?{
        //?????dog:?numOrStr;
        //?????cat:?numOrStr;
        //?????fish:?numOrStr;
        //?}

        Pick

        Pick譯為挑選/選擇, 作用是從一個復(fù)合類型中,取出幾個想要的類型的組合一個新的類型

        ts中的聲明

        /**
        ?*?From?T,?pick?a?set?of?properties?whose?keys?are?in?the?union?K
        ?*/

        type?Pick?=?{
        ??[P?in?K]:?T[P];
        };

        K extends keyof T的作用是約束K的key在T的key中,不能超出這個范圍,否則會報錯的

        keyof

        • keyof 用于獲取某種類型的所有鍵,其返回類型是聯(lián)合類型
        //?keyof?用于獲取某種類型的所有鍵,其返回類型是聯(lián)合類型
        interface?B?{
        ??id:?number;
        ??name:?string;
        ??age:?number;
        }

        type?B1?=?keyof?B;
        //?type?B1?=?"id"?|?"name"?|?"age"

        extends

        這里的extends并不是用來繼承的, 而是用來限制類型

        //?對象extends
        type?T?=?{
        ??id:?number;
        ??name:?string;
        }

        type?K?=?{
        ??id:?number;
        }
        type?IType?=?K?extends?T???K?:?T;
        //?type?IType?=?{
        //?????id:?number;
        //?????name:?string;
        //?}
        //?此處?K?extends?T?限制K中必須有T的所有屬性,?通俗點說就是T必須是K的子集


        //?聯(lián)合類型extends
        type?T?=?"id"?|?"name";
        type?K?=?"id";
        type?IType?=?K?extends?T???K?:?T;
        //?type?IType?=?"id"
        //?此處限制為K必須包含于T,通俗點說就是K是T的子集

        使用Pick挑選屬性組成新的類型

        interface?B?{
        ??id:?number;
        ??name:?string;
        ??age:?number;
        }

        type?PickB?=?Pick"id"?|?"name">;

        //?type?PickB?=?{
        //?????id:?number;
        //?????name:?string;
        //?}

        Exclude

        Exclude?譯為排除/不包括,?Exclude?表示從T中排除那些可分配給U的類型, 簡單點說就是將 T 中某些屬于 U 的類型移除掉。也可理解為取補(bǔ)集

        ts中的聲明

        /**
        ?*?Exclude?from?T?those?types?that?are?assignable?to?U
        ?*/

        type?Exclude?=?T?extends?U???never?:?T;

        //?例子1
        type?T?=?{
        ??name:?string
        ??age:?number
        }

        type?U?=?{
        ??name:?string
        }

        type?IType?=?Exclude
        //?type?IType?=?"age"

        type?T0?=?Exclude<"a"?|?"b"?|?"c",?"a"?|?"b">
        //?type?T0?=?"c"
        type?T1?=?Exclude<"a"?|?"b"?|?"c",?"a"?|?"b"?|?'s'>
        //?type?T1?=?"c"

        Extract

        Extract?譯為提取,?Extract從T中提取那些可分配給U的類型, 簡單點說就是提取T中,U也有的元素,也可理解為取交集

        ts中的定義

        /**
        ?*?Extract?from?T?those?types?that?are?assignable?to?U
        ?*/

        type?Extract?=?T?extends?U???T?:?never;

        type?T0?=?Extract<"a"?|?"b"?|?"c",?"a"?|?"f">
        //?type?T0?=?"a"

        type?T?=?{
        ??name:?string
        ??age:?number
        }

        type?U?=?{
        ??name:?string
        }

        type?IType?=?Extract
        //?type?IType?=?"name"

        ConstructorParameters

        ConstructorParameters?譯為構(gòu)造函數(shù)參數(shù), 獲取元組中構(gòu)造函數(shù)類型的參數(shù)

        ts中的聲明

        /**
        ?*?Obtain?the?parameters?of?a?constructor?function?type?in?a?tuple
        ?*/

        type?ConstructorParameters<T?extends?new?(...args:?any)?=>?any>?=?T?extends?new?(...args:?infer?P)?=>?any???P?:?never;

        可以用來獲取類的參數(shù)類型組成的元組類型

        class?People?{
        ??name:?string
        ??age:?number

        ??constructor(name:?string)?
        {
        ????this.name?=?name;
        ??}
        }


        type?IType?=?ConstructorParameters
        //?type?IType?=?[name:?string]
        //?注意這里typeof操作是取類型的作用

        infer

        表示在 extends 條件語句中待推斷的類型變量

        //?例子1
        //?若T是Array類型,則返回T的泛型,否則返回never類型
        type?Union?=?T?extends?Array???U:?never

        type?a?=?{
        ??name:?string
        }

        type?b?=?string[]


        type?c??=?Union
        //?type?c?=?string
        type?d?=?Union
        //?type?d?=?never


        //?例子2
        //?若T滿足(param:?infer?P)?=>?any,則返回函數(shù)入?yún)⒌念愋?,否則直接返回T
        type?ParamType?=?T?extends?(param:?infer?P)?=>?any???P:?T;
        ?
        interface?IDog?{
        ????name:?string;
        ????age:number;
        }
        ?
        type?Func?=?(dog:IDog)?=>?void;
        ?
        type?Param?=?ParamType;?//?IDog
        type?TypeString?=?ParamType?//string

        理解了infer?我們在回來看ts中ConstructorParameters?的聲明

        type?ConstructorParameters<T?extends?new?(...args:?any)?=>?any>?=?T?extends?new?(...args:?infer?P)?=>?any???P?:?never;

        //?T?extends?new?(...args:?any)?=>?any?首先給T加了個約束?必須滿足new?(...args:?any)?=>?any?也就是說T必須是構(gòu)造函數(shù)類型

        //?T?extends?new?(...args:?infer?P)?=>?any???P?:?never
        //?T若滿足new?(...args:?any)?=>?any?則返回所有入?yún)⒌念愋??否則返回never

        InstanceType

        InstanceType?譯為實例類型, 用來獲取構(gòu)造函數(shù)的返回類型

        ts中的定義

        /**
        ?*?Obtain?the?return?type?of?a?constructor?function?type
        ?*/

        type?InstanceType<T?extends?new?(...args:?any)?=>?any>?=?T?extends?new?(...args:?any)?=>?infer?R???R?:?any;

        class?People?{
        ??name:?string
        ??age:?number

        ??constructor(name:?string)?
        {
        ????this.name?=?name;
        ??}
        }

        type?IType?=?InstanceType
        //?type?IType?=?People
        //?因為constructor默認(rèn)返回this
        //?constructor?People(name:?string):?People

        NonNullable

        NonNullable?譯為不可為空,?NonNullable從T中排除null和undefined

        ts 中的定義

        /**
        ?*?Exclude?null?and?undefined?from?T
        ?*/

        type?NonNullable?=?T?extends?null?|?undefined???never?:?T;

        type?example?=?NonNullable
        //?type?example?=?string?|?number

        Parameters & ReturnType

        ts中的定義

        /**
        ?*?Obtain?the?parameters?of?a?function?type?in?a?tuple
        ?*/

        type?Parameters<T?extends?(...args:?any)?=>?any>?=?T?extends?(...args:?infer?P)?=>?any???P?:?never;

        /**
        ?*?Obtain?the?return?type?of?a?function?type
        ?*/

        type?ReturnType<T?extends?(...args:?any)?=>?any>?=?T?extends?(...args:?any)?=>?infer?R???R?:?any;

        定義時寫的很明確,不過多贅述

        type?IFoo?=?(
        ??uname:?string,
        ??uage:?number
        )?=>?{
        ??name:?string;
        ??age:?number;
        };
        //參數(shù)類型
        type?Ibar?=?Parameters;
        //?type?Ibar?=?[uname:?string,?uage:?number]
        type?T0?=?ReturnType;
        //?type?T0?=?{
        //?????name:?string;
        //?????age:?number;
        //?}

        readonly & ReadonlyArray

        interface?ReadonlyArray<T>?{
        ????/**?Iterator?of?values?in?the?array.?*/
        ????[Symbol.iterator]():?IterableIterator;

        ????/**
        ?????*?Returns?an?iterable?of?key,?value?pairs?for?every?entry?in?the?array
        ?????*/

        ????entries():?IterableIterator<[number,?T]>;

        ????/**
        ?????*?Returns?an?iterable?of?keys?in?the?array
        ?????*/

        ????keys():?IterableIterator;

        ????/**
        ?????*?Returns?an?iterable?of?values?in?the?array
        ?????*/

        ????values():?IterableIterator;
        }

        interface?Person?{
        ??readonly?id:?number;
        }
        const?data:?Person?=?{
        ??id:?456,
        };

        data.id?=?789;
        //?無法分配到?"id"?,因為它是只讀屬性。ts(2540)

        const?arr:?number[]?=?[1,?2,?3,?4];

        let?ro:?ReadonlyArray?=?arr;

        ro.push(444);
        //?類型“readonly number[]”上不存在屬性“push”。ts(2339)

        總結(jié)

        ts中有很多特性都可以在lib.es5.ts中去查看, 里面定義的接口和類型非常多,主要是理解ts定義的套路,就能舉一反三,


        瀏覽 138
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            先锋资源成人 | 乱情家庭(家庭乱情)小说 | 映画一区二区三区 | 免费无码真人在线 | 揉我奶 啊 嗯高潮和尚免费 | 亚洲v欧美 | 三级天天操 | 好看的印度三色电费 | 色视频一区 | 五月丁香无码视频 |