簡體   English   中英

Typescript 不理解 T 在特定的復雜自定義類型中擴展接口

[英]Typescript not understanding that T extends interface in a specific complex custom type

所以我使用的是我從這里得到的Paths類型,完全公開,我不完全理解它是如何構建的,它可能會幫助我理解問題,我將在底部實現它。 總之,如果我有接口:

interface Person {
  name: string,
  contacts: {
    email: string,
    phone: string,
  }
}

然后Paths<Person>將導致文字類型的聯合:

'name' | 'contacts' | 'contacts.email' | 'contacts.phone'

但是當嘗試將它與擴展某種類型的泛型一起使用時,我遇到了奇怪的麻煩。

function foo<T extends Person> {
  let personParamGood: Paths<Person>;
  personParamGood = 'name' // great, works.
  
  let personParamBad: Paths<T>
  personParamBad = 'name' // typescript screams at me
  
}

我得到的類型錯誤說

error TS2322: Type '"name"' is not assignable to type 'T extends object ? { [K in keyof T]-?: K extends string | number ? `${K}` | Join<K, T[K] extends object ? { [K in keyof T[K]]-?: K extends string | number ? `${K}` | Join<K, never> : never; }[keyof T[K]] : ""> : never; }[keyof T] : ""'.

我不明白為什么, T基本上不應該是Person

它確實適用於簡單的類型:

function foo<T extends Person> {
  let personParamGood: keyof Person;
  personParamGood = 'name' // great, works.
  
  let personParamGoodToo: keyof T
  personParamGoodToo = 'name' // great, works.
  
}

我的Paths實現:

type Prev = [never, 0, 1, 2, 3, 5, 6, 7, 8, ...0[]];

type Join<K, P> = K extends string | number
  ? P extends string | number
    ? `${K}${'' extends P ? '' : '.'}${P}`
    : never
  : never;

export type Paths<T, D extends number = 10> = [D] extends [never]
  ? never
  : T extends object
  ? {
      [K in keyof T]-?: K extends string | number
        ? `${K}` | Join<K, Paths<T[K], Prev[D]>>
        : never;
    }[keyof T]
  : '';

這是因為T永遠不會function 實現中解析,因為它可以是任何東西。 您在其上添加了extends Person約束,但它仍然可以是擴展Person的任何內容。 實際的T型僅在 function 之外已知。

請注意當您 hover person變量時此代碼如何工作:

interface Person {
  name: string,
  contacts: {
    email: string,
    phone: string,
  }
}

interface ExtendedPerson extends Person {
  address: string;
}

declare function foo<T extends Person>(): Paths<T>;

const person = foo<ExtendedPerson>();

但是您將永遠無法使T (因此Paths<T> )解析為 function 實現中的實際類型,這就是 generics 在 Z558B544CF685F39D34E4903E3 中的工作方式。

暫無
暫無

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

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