<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [TS手冊(cè)學(xué)習(xí)] 03_函數(shù)相關(guān)知識(shí)點(diǎn)

      TS官方手冊(cè):TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org)

      函數(shù)類型表達(dá)式

      使用類似于箭頭表達(dá)式的形式來(lái)描述一個(gè)函數(shù)的類型。

      function greeter(fn: (a: string) => void) {
        fn("Hello, World");
      }
      

      上述代碼中,fn: (a:string) => void表示變量fn是一個(gè)函數(shù),這個(gè)函數(shù)有一個(gè)參數(shù)a,是string類型,且這個(gè)函數(shù)的返回值類型為void,即沒有返回值。

      調(diào)用簽名

      在 JS 中,函數(shù)是對(duì)象,除了可以調(diào)用也可以擁有自己的屬性。而使用函數(shù)類型表達(dá)式無(wú)法聲明這一部分屬性的類型。

      可以將函數(shù)視為一個(gè)對(duì)象,聲明一個(gè)類型,其中包含多個(gè)屬性的類型聲明,并使用調(diào)用簽名來(lái)描述函數(shù)參數(shù)和返回值的類型,取代原先函數(shù)類型表達(dá)式的寫法。

      type DescribableFunction = {
        description: string;
        (someArg: number): boolean;
      };
      

      在這個(gè)例子中,DescribableFunction是一個(gè)函數(shù)類型,description是這個(gè)函數(shù)類型實(shí)例對(duì)象的一個(gè)屬性名,類型為string。而這個(gè)函數(shù)的參數(shù)列表類型聲明為:(someArg: number),返回值類型為boolean

      需要注意,在這種寫法中,參數(shù)列表和返回值類型之間是用:隔開,而函數(shù)類型表達(dá)式是使用=>

      構(gòu)造簽名

      搭配構(gòu)造函數(shù)使用,在調(diào)用簽名的語(yǔ)法前面加上new

      type SomeConstructor = {
        new (s: string): SomeObject;
      };
      

      泛型函數(shù)

      如果函數(shù)的參數(shù)類型與返回值的參數(shù)類型存在關(guān)聯(lián),可以使用泛型:

      function firstElement<Type>(arr: Type[]): Type | undefined {
        return arr[0];
      }
      
      // s是'string'類型
      const s = firstElement(["a", "b", "c"]);
      // n是'number'類型
      const n = firstElement([1, 2, 3]);
      // u是undefined類型
      const u = firstElement([]);
      

      多類型

      function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {
        return arr.map(func);
      }
      

      類型約束

      泛型支持函數(shù)傳入不同的類型,當(dāng)需要約束時(shí),例如要求傳入的參數(shù)類型必須包含一個(gè)某類型的屬性,則可以:

      function longest<Type extends { length: number }>(a: Type, b: Type) {
        if (a.length >= b.length) {
          return a;
        } else {
          return b;
        }
      }
      

      使用<Type extends { x : y}>實(shí)現(xiàn),extends表示繼承于類型{x:y},表示類型Type應(yīng)該包含y類型的屬性x

      需要注意如果函數(shù)返回值類型為Type,那么不能返回類型為{x:y},因?yàn)門ype包含{x:y},而可能存在比{x:y}更多的屬性。

      指定類型參數(shù)

      function combine<Type>(arr1: Type[], arr2: Type[]): Type[] {
        return arr1.concat(arr2);
      }
      
      // 報(bào)錯(cuò),因?yàn)楦鶕?jù)第一次參數(shù),Type會(huì)被識(shí)別為number,但是第二個(gè)參數(shù)卻是string[]類型。
      const arr = combine([1, 2, 3], ["hello"]);
      

      如果執(zhí)意這么設(shè)計(jì)函數(shù)的話,可以考慮使用聯(lián)合類型:

      const arr = combine<string | number>([1, 2, 3], ["hello"]);
      
      使用泛型函數(shù)的建議
      1. 盡可能使用類型參數(shù)本身,而不去使用類型約束。

        // Good: 返回值類型會(huì)被推斷為Type
        function firstElement1<Type>(arr: Type[]) {
          return arr[0];
        }
        // Bad: 返回值類型會(huì)被推斷為any
        function firstElement2<Type extends any[]>(arr: Type) {
          return arr[0];
        }
        
      2. 盡可能少地使用類型參數(shù)。

        過(guò)多的類型參數(shù)會(huì)使得函數(shù)難以閱讀,盡量確保類型參數(shù)與多個(gè)值相關(guān)(例如與函數(shù)參數(shù)和返回值都有關(guān))再使用。

        // Good: 只用了Type一個(gè)類型參數(shù)
        function filter1<Type>(arr: Type[], func: (arg: Type) => boolean): Type[] {
          return arr.filter(func);
        }
        // Bad: Func這個(gè)類型參數(shù)是多余的,只用在了一個(gè)函數(shù)參數(shù)
        function filter2<Type, Func extends (arg: Type) => boolean>(
          arr: Type[],
          func: Func
        ): Type[] {
          return arr.filter(func);
        }
        
      3. 如果類型參數(shù)只出現(xiàn)在一個(gè)位置,那么這個(gè)類型參數(shù)很可能不是必要的。

        使用泛型是因?yàn)楹瘮?shù)中有若干個(gè)值的類型存在關(guān)聯(lián),如果類型參數(shù)只出現(xiàn)在一個(gè)位置,很可能不是必要的。

        // Bad: Str是不必要的
        function greet<Str extends string>(s: Str) {
          console.log("Hello, " + s);
        }
        // Good
        function greet(s: string) {
            console.log("Hello, " + s);
        }
        

      可選參數(shù)列表

      function f(x?: number) {
        // ...
      }
      f(); // OK
      f(10); // OK
      

      :上面的代碼中x的類型實(shí)際為number|undefined,當(dāng)不傳入該參數(shù)的時(shí)候就是undefined

      如果考慮設(shè)置默認(rèn)值,如下,那么x的類型就會(huì)變成number,排除了undefined的情況。

      function f(x = 10) {
        // ...
      }
      

      :只要一個(gè)參數(shù)是可選的,那么這個(gè)參數(shù)就可以被傳入undefined

      回調(diào)函數(shù)的可選參數(shù)

      在設(shè)計(jì)一個(gè)回調(diào)函數(shù)的函數(shù)類型時(shí),不要使用可選參數(shù)。

      函數(shù)重載

      function makeDate(timestamp: number): Date;
      function makeDate(m: number, d: number, y: number): Date;
      function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
        if (d !== undefined && y !== undefined) {
          return new Date(y, mOrTimestamp, d);
        } else {
          return new Date(mOrTimestamp);
        }
      }
      const d1 = makeDate(12345678);
      const d2 = makeDate(5, 5, 5);
      // 報(bào)錯(cuò)
      const d3 = makeDate(1, 3);
      

      如上述代碼,先寫兩個(gè)重載函數(shù)簽名(overload signatures),然后再寫一個(gè)函數(shù)兼容實(shí)現(xiàn)這兩個(gè)簽名,叫做實(shí)現(xiàn)簽名(implementation signature)。

      在調(diào)用函數(shù)的時(shí)候,需要以重載簽名為標(biāo)準(zhǔn),不能以實(shí)現(xiàn)簽名為標(biāo)準(zhǔn)。也就是說(shuō),上面這段代碼中的函數(shù)makeDate,要么傳入1個(gè)參數(shù),要么傳入3個(gè)參數(shù),不能傳入2個(gè)參數(shù)。

      • 從外部無(wú)法看見實(shí)現(xiàn)的簽名。在編寫重載函數(shù)時(shí),應(yīng)該始終在函數(shù)的實(shí)現(xiàn)之上有兩個(gè)或多個(gè)簽名。
      • 實(shí)現(xiàn)簽名與重載簽名之間要兼容。
      • 當(dāng)可以使用聯(lián)合類型函數(shù)參數(shù)解決問題時(shí),就不要使用函數(shù)重載。

      聲明this的類型

      const db = getDB();
      const admins = db.filterUsers(function (this: User) {
        return this.admin;
      });
      

      其它與函數(shù)相關(guān)的類型

      void

      void作為函數(shù)的返回值類型,表示函數(shù)沒有返回值。

      在 JS 中沒有返回值的函數(shù)會(huì)返回 undefined,但是在 TS 中undefinedvoid是不同的。

      當(dāng)函數(shù)返回值聲明為void,仍可以在函數(shù)體中return內(nèi)容,但不管返回了什么值,最終接收函數(shù)返回值的那個(gè)變量都會(huì)是void類型。

      type voidFunc = ()=>void;
      const f: voidFunc = ()=> true;
      
      // 這里value的類型會(huì)被推斷為void
      const value = f();
      
      object

      object類型是除了stringnumberbigintbooleansymbolnullundefined的其它類型。

      object類型與空對(duì)象類型{}不同,與全局類型Object也不同。永遠(yuǎn)不要使用Object類型,而是使用object

      在 JS 中,函數(shù)也是對(duì)象;在 TS 中,函數(shù)也被認(rèn)為是object類型。

      unknown

      unknownany非常類似,但是unknown更安全。

      因?yàn)?code>unknown類型變量的任何操作都是非法的,這迫使大多數(shù)操作之前需要對(duì)unknown類型變量進(jìn)行類型的檢查。

      any類型的值執(zhí)行操作之前不需要進(jìn)行任何檢查。

      function f1(a: any) {
        a.b(); // OK
      }
      
      function f2(a: unknown) {
        a.b(); // ERROR: 'a' is of type 'unknown'.
      }
      

      unknown類型只能賦值給anyunknown類型。

      unknown類型的意義:TS 不允許我們對(duì)類型為 unknown 的值執(zhí)行任意操作。我們必須首先執(zhí)行某種類型檢查以縮小我們正在使用的值的類型范圍。

      可以使用類型收束(Narrowing)的操作將unknown縮小到具體的類型,再進(jìn)行后續(xù)操作。

      never

      never通常描述返回值類型,表示永遠(yuǎn)不返回值。與void不同,使用never意味著函數(shù)會(huì)拋出一個(gè)異常,或者程序會(huì)被終止。

      function fail(msg: string): never {
        throw new Error(msg);
      }
      

      另一種情況下也會(huì)出現(xiàn)never,就是當(dāng)聯(lián)合類型被不斷收窄到空時(shí),就是never

      function fn(x: string | number) {
        if (typeof x === "string") {
          // do something
        } else if (typeof x === "number") {
          // do something else
        } else {
          x; // 這里x的類型是'never'
        }
      }
      
      Function

      全局類型Function聲明的變量包含了 JS 中函數(shù)所擁有的所有屬性和方法,例如bindcallapply

      Function聲明的變量是可執(zhí)行的,并且返回any

      這種函數(shù)類型聲明方式很不安全,因?yàn)榉祷?code>any,最好使用函數(shù)類型表達(dá)式聲明:()=>void

      function doSomething(f: Function) {
        return f(1, 2, 3);
      }
      

      不定長(zhǎng)參數(shù)列表

      在 TS 中,不定長(zhǎng)參數(shù)列表的類型應(yīng)該被聲明為Array<T>T[]或元組類型。

      function multiply(n: number, ...m: number[]) {
        return m.map((x) => n * x);
      }
      

      spread語(yǔ)法可以展開可迭代對(duì)象(例如數(shù)組,對(duì)象)變成不定長(zhǎng)的參數(shù)列表。例如push函數(shù)可以接收多個(gè)參數(shù)。

      const arr1 = [1, 2, 3];
      const arr2 = [4, 5, 6];
      arr1.push(...arr2);
      

      但需要注意,TS 認(rèn)為數(shù)組是可變的,數(shù)組長(zhǎng)度是可變的。

      觀察下面的案例代碼:

      const args = [8, 5];
      const angle = Math.atan2(...args);
      

      盡管Math.atan2接收兩個(gè)number類型的參數(shù),而args也剛好是長(zhǎng)度為2的number[]類型數(shù)組,展開后剛好。

      但是這段代碼會(huì)報(bào)錯(cuò),因?yàn)閿?shù)組是可變的。

      一種較為直接的解決方法是使用const

      // 視為長(zhǎng)度為2的元組
      const args = [8, 5] as const;
      // 現(xiàn)在不會(huì)報(bào)錯(cuò)了
      const angle = Math.atan2(...args);
      

      參數(shù)解構(gòu)的類型聲明

      function sum({ a, b, c }: { a: number; b: number; c: number }) {
        console.log(a + b + c);
      }
      

      或者使用type簡(jiǎn)化:

      type ABC = { a: number; b: number; c: number };
      function sum({ a, b, c }: ABC) {
        console.log(a + b + c);
      }
      
      posted @ 2023-11-30 14:17  feixianxing  閱讀(94)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲sm另类一区二区三区| 亚洲禁精品一区二区三区| 99久久精品费精品国产一区二| 精品无码国产自产拍在线观看蜜 | 欧日韩无套内射变态| 欧美日本在线一区二区三区| 中日韩精品视频一区二区三区 | 久久婷婷大香萑太香蕉av人| 中文字幕日韩区二区三区| 东方av四虎在线观看| 中文字幕精品人妻丝袜| 2018年亚洲欧美在线v| 国产91小视频在线观看| 亚洲v欧美v日韩v国产v| 爱性久久久久久久久| 久青草国产在视频在线观看| 国产成人无码AV片在线观看不卡| 偷偷做久久久久免费网站| 亚洲欧洲日韩国内高清| 国产综合视频一区二区三区| 亚洲国产成人无码av在线影院| 日本人一区二区在线观看| 中文字幕有码日韩精品| 亚洲精品国产中文字幕| 日本久久精品一区二区三区 | 国产精品一区二区三区四区| 婷婷四房播播| 亚洲经典av一区二区| 亚洲欧美综合精品成| 国产在热线精品视频99公交| 国产高潮刺激叫喊视频| 一 级做人爱全视频在线看| 久久精品国产精品第一区| 亚洲自偷自拍熟女另类| 无码伊人66久久大杳蕉网站谷歌| 亚洲高清aⅴ日本欧美视频| 亚洲成人一区| 国内视频偷拍一区,二区,三区| 国内少妇人妻偷人精品视频| 免费无码AV一区二区波多野结衣| 免费无码肉片在线观看|