簡體   English   中英

Typescript 是如何推斷出 Generics 的,為什么它在一種情況下不起作用?

[英]How does Typescript infer Generics and why does it not work in one case?

為什么f2(f1)會出現 Typescript 錯誤? 對我來說,f2、f3 和 f4 似乎具有相同的類型。 它只是宣布不同。 f4與f2或f3的區別在哪里?

我有以下示例:

Typescript 游樂場

代碼:

interface FullType {
  id: string;
  order_no: number;
}

interface OrderType {
  [key: string]: any;
  order_no: number;
}

const f1 = (d1: FullType): Promise<FullType> => {
  return new Promise(() => {
    return d1;
  });
};

function f2<Type extends OrderType, Fn extends (t: Type) => Promise<Type>>(
  f: Fn,
): void {
  //
}

function f3<Type extends OrderType>(f: (t: Type) => Promise<Type>): void {
  //
}

function f4<Type1 extends Type2, Type2 extends OrderType>(
  f: (item: Type1) => Promise<Type1>,
): void {
  //
}

f2(f1); // why is here a warning
f3(f1);
f4(f1);

在 TypeScript 中,generics 通常工作得很好,但是當您開始使用已經擴展的通用類型來定義也將被擴展的新通用類型時 - 這就是問題發生的地方。 一般來說, TypeScript 中的通用約束(例如<T> )不被視為可以進一步推斷的類型,這意味着雖然像f4中那樣擴展擴展類型是無害的,但擴展也使用 generics 的新定義類型是有問題的:

f4非常好:

<Type1 extends Type2, Type2 extends OrderType>

f3也很好,因為它沒有擴展類型來定義回調,而是直接創建:

f: (t: Type) => Promise<Type>

f2是問題開始出現的地方,因為參數類型正在使用也使用擴展值的擴展泛型類型。 這會導致類型默認返回到OrderType並且因為FullType不直接等於OrderType你會觀察到該錯誤:

Fn extends (t: Type) => Promise<Type>

這可以通過在單獨的類型中定義它來進一步說明:

type CustomCallback<T> = (t: T) => Promise<T>;

// This will work just fine
function f2<Type extends OrderType>(f: CustomCallback<Type>): void {
  //
}

// this will not
function f2<Type extends OrderType, paramType extends CustomCallback<Type>>(f: paramType): void {
  //
}

這是游樂場鏈接

我必須另外提到,關鍵字extends從類型中提取所有已知屬性,並允許使用其他值,因為索引簽名[key: string]: any; OrderType中定義的屬性,因此這就是f3f4沒有顯示錯誤的原因。 但是,如果您在其中任何一個中使用直接類型,您將開始看到警告,因為FullType不等於OrderType

function f3(f: (t: OrderType) => Promise<OrderType>): void {
  //
}

f3(f1); // warning

總而言之,作為一般規則,盡量避免擴展已經使用擴展變量的泛型類型。

暫無
暫無

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

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