簡體   English   中英

如何理解復雜的打字稿泛型類型?

[英]How to understand complicated typescript generic types?

我正在檢查RxJS api文件。 我總是在理解頂部寫的奇怪語法時遇到問題,這就像下面的例子一樣:

combineLatest<O extends ObservableInput<any>, R>(...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]): Observable<R>

我想了解這種語法並進一步自己編寫。

所以,如果有人解釋上面例子中發生了什么,那將是很有幫助的。

function combineLatest<O extends ObservableInput<any>, R>(...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]): Observable<R>

讓我們分解吧。

好的,這是一個功能

function combineLatest(args): Result

它接受一些參數並返回Result類型的Result

但它也是一種稱為泛型函數的特殊函數。 泛型的目的是在成員之間提供有意義的類型約束。

function combineLatest<T>(args): Result
                      /\
           now it's a generic function

這里的T是一個類型變量 ,它允許我們捕獲用戶提供的類型,以便我們以后可以使用該信息。 例如,我們可以使用T作為返回類型:

function combineLatest<T>(args): T

以便以下調用:

combineLatest<string>(someParams) // returns `string`

將為我們提供類型string的結果,因為我們明確地將T設置為string

我們也可以將該T類型變量用於函數的任何參數。

function combineLatest<T>(arg: T): T

現在我們可以使用類型參數推斷

combineLatest('someStr') // returns `string`

也就是說,我們告訴編譯器根據我們傳入的參數的類型自動為我們設置T的值。我們傳遞了一個string以便我們得到一個string

我們可以根據需要使用盡可能多的類型變量。 我們也可以隨意打電話給他們。

function combineLatest<Type1, Type2, ...>(...)

泛型很棒,有時我們想用我們傳入的參數做一些動作:

function combineLatest<T>(arg: T): T {
  arg.name = arg.name.toLowerCase(); // Property 'name' does not exist on type 'T'
  return arg;
}

正如您所看到的,編譯器無法理解arg類型。 為了解決這個問題,我們可以在extends運算符的幫助下表示對T類型變量的約束:

interface ItemWithName {
  name: string;
}
function combineLatest<T extends ItemWithName>(arg: T): T {
  arg.name = arg.name.toLowerCase();
  return arg;
}

現在編譯器知道arg的name屬性為string


現在讓我們回到我們的初始聲明:

combineLatest<O extends ObservableInput<any>, R>(...): Observable<R>

我們在這里可以看到這個函數使用兩個類型變量:

  • O型變量代表Observable。 它被約束為ObservableInput<any>類型
  • R代表結果

combineLatest函數的結果應該是類型R Observable 例如,我們可以通過調用此函數強制該類型:

combineLatest<any, MyClass>(...)  // returns Observable<MyClass>

現在讓我們看一下這個函數可以采用的參數:

...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]

我們可以在這里看到其余參數運算符。 讓我們簡化上面的表達式,以便我們想象如下:

...observables: CombinedType[]

這意味着combineLatest函數可以接受零個或多個參數,這些參數稍后將聚集到一個變量observables

combineLatest();                 // without parameters
combineLatest(obs1);             // one parameter
combineLatest(obs1, obs2, ..etc) // many parameters

那么這個參數的類型是什么

           CombinedType

O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike

有可能:

  • O類型變量的類型,它被約束為我們前面討論過的ObservableInput<any>類型

  • 或者它可以是函數(...values: ObservedValueOf<O>[]) => R ,它接受零個或多個ObservedValueOf<O>類型的參數並返回R類型變量類型。 請注意,此返回類型可用於推斷combineLatest函數的返回類型。

  • 或者它可以是SchedulerLike接口的類型。


我認為如果將它們拆分成小塊,理解TypeScript類型聲明應該沒有任何問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM