自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何聲明 Currying 函數(shù)的類型?

開發(fā) 前端
我們需要獲取參數(shù)列表的類型和函數(shù)的返回值類型。參數(shù)列表類型要包含參數(shù)的名稱和參數(shù)的類型。那么如何獲取函數(shù)類型的參數(shù)列表類型和返回值類型呢?

Challenge

在本次挑戰(zhàn)中,您需要為 Currying 函數(shù)聲明相應(yīng)的類型,以幫助 TypeScript 編譯器推斷出正確的類型。

declare function Currying(fn: any): any

const curried1 = Currying((a: string, b: number, c: boolean) => true)
const curried2 = Currying((a: string, b: number, c: boolean, d: boolean, e: boolean, f: string, g: boolean) => true)
const curried3 = Currying(() => true)

type cases = [
  Expect<Equal<
    typeof curried1,
     (a: string) => (b: number) => (c: boolean) => true>>,
  Expect<Equal<
    typeof curried2,
     (a: string) => (b: number) => (c: boolean) => (d: boolean) => (e: boolean) => (f: string) => (g: boolean) => true
  >>,
  Expect<Equal<typeof curried3, () => true>>,
]

在上面的代碼中,我們使用了兩個工具類型 Expect 和 Equal,它們的實現(xiàn)代碼如下:

type Expect<T extends true> = T
type Equal<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? true : false

Solution

首先,我們來分析一下第一個測試用例:

圖片圖片

由上圖可知,我們需要獲取參數(shù)列表的類型和函數(shù)的返回值類型。參數(shù)列表類型要包含參數(shù)的名稱和參數(shù)的類型。那么如何獲取函數(shù)類型的參數(shù)列表類型和返回值類型呢?這時我們可以使用 TypeScript 內(nèi)置的 Parameters 和 ReturnType 工具類型。

type T0 = Parameters<() => true> // []
type T1 = Parameters<(a: string, b: number, c: boolean) => true>
// [a: string, b: number, c: boolean]

type T2 = ReturnType<() => void> // void
type T3 = ReturnType<(a: string, b: number, c: boolean) => true> // true

圖片圖片

在以上代碼中,Parameters 工具類型用于獲取函數(shù)類型的參數(shù)列表類型,它返回的是元組類型。而 ReturnType 工具類型則用于獲取函數(shù)類型的返回值類型。它們的實現(xiàn)代碼如下所示:

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

在以上代碼中,使用了 TypeScript 條件類型和 infer 類型推斷。了解完以上代碼,我們就知道如何獲取函數(shù)類型的參數(shù)列表類型和返回值類型了。

接下來,我們要實現(xiàn)的功能就是使用函數(shù)的參數(shù)類型和返回值類型生成新的函數(shù)類型。下面我們來定義一個新的 ToCurrying 工具類型,它包含兩個類型變量 Args 和 Return,分別表示參數(shù)的類型和返回值類型:

type ToCurrying<Args extends unknown[], Return> = unknown

然后,我們來繼續(xù)分析第一個測試用例:

const curried1 = Currying((a: string, b: number, c: boolean) => true)

type cases = [
  Expect<Equal< typeof curried1,
    (a: string) => (b: number) => (c: boolean) => true>>
]

圖片圖片

參考以上的圖片,我們可以總結(jié)出 ToCurrying 工具類型的處理流程:

圖片圖片

根據(jù)上述的處理流程,我們可以利用 TypeScript 條件類型、infer 類型推斷和遞歸類型來實現(xiàn)對應(yīng)的功能:

type ToCurrying<Args extends unknown[], Return> = 
  Args extends [...infer Head, infer Tail] 
   ? ToCurrying<Head, (arg: Tail) => Return> 
   : Return
   
type C0 = ToCurrying<[a: string, b: number, c: boolean], true>
// (arg: string) => (arg: number) => (arg: boolean) => true

type C1 = ToCurrying<[a: string, b: number, c: boolean, d: boolean, e: boolean, 
  f: string, g: boolean], true>
// (arg: string) => (arg: number) => (arg: boolean) => (arg: boolean) 
//   => (arg: boolean) => (arg: string) => (arg: boolean) => true

有了 ToCurrying 工具類型之后,我們來更新前面聲明的 Currying 函數(shù):

declare function Currying<T extends Function>(fn: T):
    T extends (...args: infer Args) => infer Return ?
    ToCurrying<Args, Return>
    : never
    
const curried1 = Currying((a: string, b: number, c: boolean) => true)
const curried2 = Currying((a: string, b: number, c: boolean, d: boolean, e: boolean, f: string, g: boolean) => true)
const curried3 = Currying(() => true)

type cases = [
  Expect<Equal<
    typeof curried1,
     (a: string) => (b: number) => (c: boolean) => true>>,
  Expect<Equal<
    typeof curried2,
     (a: string) => (b: number) => (c: boolean) => (d: boolean) => (e: boolean) 
       => (f: string) => (g: boolean) => true
  >>,
  Expect<Equal<typeof curried3, () => true>>,
]

更新后的 Currying 函數(shù),已經(jīng)可以滿足前兩個測試用例。但還不能滿足最后一個測試用例:

圖片圖片

這是因為獲取 () => true 函數(shù)類型的參數(shù)列表類型時,返回的是空元組類型,針對這種情形,我們需要進(jìn)行對應(yīng)的處理:

declare function Currying<T extends Function>(fn: T):
    T extends (...args: infer Args) => infer Return ?
    Args extends [] 
    ? () => Return
    : ToCurrying<Args, Return>
    : never

在以上代碼中,當(dāng)發(fā)現(xiàn) Args 類型變量對應(yīng)的類型是空元組類型的話,我們直接返回 () => Return 函數(shù)類型。之后,我們就通過了所有的測試用例。最后,我們來看一下完整的代碼:

declare function Currying<T extends Function>(fn: T):
    T extends (...args: infer Args) => infer Return ?
    Args extends []
    ? () => Return
    : ToCurrying<Args, Return>
    : never

type ToCurrying<Args extends unknown[], Return> =
    Args extends [...infer Head, infer Tail]
    ? ToCurrying<Head, (arg: Tail) => Return>
    : Return
責(zé)任編輯:武曉燕 來源: 全棧修仙之路
相關(guān)推薦

2021-09-28 07:12:10

avaScriptCurrying柯里化

2009-09-01 18:05:17

C#類型聲明

2010-05-21 17:14:18

MySQL 數(shù)字類型

2021-09-15 07:56:33

函數(shù)類型Go

2011-05-30 16:11:46

Javascript

2023-03-20 08:14:11

PHP類型轉(zhuǎn)換

2014-04-16 10:54:45

Javascript遞歸調(diào)用

2022-01-04 19:21:04

函數(shù)TypeScript重載

2017-08-01 00:19:15

Javascript函數(shù)函數(shù)聲明

2009-11-16 16:59:03

PHP構(gòu)造函數(shù)

2009-08-20 10:34:46

C#中聲明API函數(shù)

2010-02-22 16:51:03

Python 解析器

2009-09-01 10:49:28

C#具有隱式類型聲明

2023-07-13 09:05:57

react hook類型types

2013-04-16 10:24:33

函數(shù)偏函數(shù)編程語言

2021-06-28 08:01:57

JS 函數(shù)表達(dá)式函數(shù)聲明

2013-07-23 13:06:50

2010-04-01 10:55:48

Oracle 數(shù)據(jù)類型

2024-01-17 06:23:35

SwiftTypeScript定義函數(shù)

2021-01-14 10:10:51

Python函數(shù)Function An
點贊
收藏

51CTO技術(shù)棧公眾號