簡體   English   中英

Typescript:使用特定的擴展接口來滿足通用“擴展”類型參數?

[英]Typescript: use specific extended interface to satisfy generic “extends” type argument?

這是一個小代碼示例(旁注:我正在運行 Typescript v3.8.3):

interface IOptions<T> {
  arg: T;
}

interface IExtraOptions extends IOptions<number> {
  arg2: string;
}

type Func = <T, OptionsT extends IOptions<T>>(options: OptionsT) => T;

const f: Func = (options: IExtraOptions): number => {
  return options.arg2 === 'dev' ? 0 : options.arg;
};

我希望這可以工作,因為IExtraOptions擴展IOptions並因此滿足了OptionsT extends IOptions<T>約束,但我得到:

類型“OptionsT”不可分配給類型“IExtraOptions”。

“IOptions”類型中缺少屬性“arg2”,但在“IExtraOptions”類型中是必需的。ts(2322)

完全刪除OptionsT參數並僅使用IOptions<T>作為“選項”的類型參數會產生相同的錯誤。 用非默認類型替換“數字”也不能解決它。 有人知道我在做什么錯嗎?

如果你有一個通用的 function,function 的 generics 類型參數是供調用者確定的,而不是用於修復某些任意類型的實現。 例如,給定您的示例,此調用將是有效的f<boolean, IOptions<boolean>>({ arg: true })並且您指定的實現不會返回 object 以滿足這些類型參數。

結論是,如果你有一個通用的 function,通常只有一個通用的 function 將滿足實現(盡管使用非常松散的類型,例如anyneverunknown也可能工作)。

如果你想創建專門的函數,不要使用泛型 function,使用恰好是 function 的泛型類型:


type Func <T, OptionsT extends IOptions<T>> =(options: OptionsT) => T;

const f: Func<number, IExtraOptions> = (options ) => {
  return options.arg2 === 'dev' ? 0 : options.arg;
};

游樂場鏈接

您還可以從TOptions派生T以簡化一些事情:


type Func <OptionsT extends IOptions<any>> =(options: OptionsT) => OptionsT['arg'];

const f: Func<IExtraOptions> = (options ) => {
  return options.arg2 === 'dev' ? 0 : options.arg;
};

游樂場鏈接

暫無
暫無

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

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