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高級特性

        共 6808字,需瀏覽 14分鐘

         ·

        2021-02-04 10:00

        小廣告招聘:?螞蟻體驗(yàn)技術(shù)部招人啦,P5起!


        永久原文地址(你的star是我最大的動(dòng)力??)

        Partial & Required

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

        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 譯為 記錄/記載, 作用是將一個(gè)類型的所有屬性值都映射到另一個(gè)類型上并創(chuàng)造一個(gè)新的類型

        ts中的聲明

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

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

        看類型的定義就可以看出來,將K中的每個(gè)屬性([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譯為挑選/選擇, 作用是從一個(gè)復(fù)合類型中,取出幾個(gè)想要的類型的組合一個(gè)新的類型

        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中,不能超出這個(gè)范圍,否則會報(bào)錯(cuò)的

        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的所有屬性,?通俗點(diǎn)說就是T必須是K的子集


        //?聯(lián)合類型extends
        type?T?=?"id"?|?"name";
        type?K?=?"id";
        type?IType?=?K?extends?T???K?:?T;
        //?type?IType?=?"id"
        //?此處限制為K必須包含于T,通俗點(diǎn)說就是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的類型, 簡單點(diǎn)說就是將 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的類型, 簡單點(diǎn)說就是提取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加了個(gè)約束?必須滿足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 譯為實(shí)例類型, 用來獲取構(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
        //?因?yàn)閏onstructor默認(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;

        定義時(shí)寫的很明確,不過多贅述

        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"?,因?yàn)樗侵蛔x屬性。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定義的套路,就能舉一反三,




        推薦閱讀




        我的公眾號能帶來什么價(jià)值?(文末有送書規(guī)則,一定要看)

        每個(gè)前端工程師都應(yīng)該了解的圖片知識(長文建議收藏)

        為什么現(xiàn)在面試總是面試造火箭?

        瀏覽 91
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        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>
            人人摸人人搞 | 日本乱轮中文字幕 | 人人妻人人澡人人爽 | 啊啊啊啊啊啊国产 | 国产成人美女久久久网站 | 丰满美女av | 黄色小说视频网址 | 国产人妖Ts一区二区三区 | 风流少妇按摩来高潮 | 女同激情久久av久久 |