簡體   English   中英

創建多個通用類型的交集類型

[英]Create Intersection Type of Multiple Generic Types

我一直在大量閱讀變量類型和TypeScript中的一些新元組,但是我很難確定我目前正在嘗試完成的功能是不可能的。

目前可以在此處看到API的確切問題:

export type Themed<T> = { theme: T };

export type ThemedStyleAugmentationFn<P, T> = (
  allProps: Partial<P> & Themed<T>
) => string;

export function augmentComponent<
  P,
  TA extends T,
  C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
  T extends object,
  O extends object = {},
  A extends keyof any = never
>(
  styledComponent: StyledComponent<C, T, O, A>,
  styleAugmentation: ThemedStyleAugmentationFn<P, TA>
): StyledComponent<C, T, O & Partial<P>, A> {
  const augmented = styled(styledComponent)`
    ${styleAugmentation}
  `;

  return augmented as StyledComponent<C, T, O & Partial<P>, A>;
}

export function multiAugment<
  P1 extends {},
  TA1 extends T,
  P2 extends {},
  TA2 extends T,
  C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
  T extends object,
  O extends object = {},
  A extends keyof any = never
>(
  styledComponent: StyledComponent<C, T, O, A>,
  styleAugmentations: [ThemedStyleAugmentationFn<P1, TA1>, ThemedStyleAugmentationFn<P2, TA2>]
): StyledComponent<C, T, O & Partial<P1 & P2>, A> {
  const augmented = styled(styledComponent)`
    ${styleAugmentations}
  `;

  return augmented as StyledComponent<C, T, O & Partial<P1 & P2>, A>;
}

augmentComponent中,簽名的重要部分在於: O & Partial<P>

multiAugment中顯式獲取兩個ThemeStyleAugmentationFun的元組它在這里: O & Partial<P1 & P2>

我希望能夠編寫一個版本的multiAugment,它可以獲取AugmentationFn的任意列表並將它們組合在一起,以便它可以支持任何arity。 可能會返回O & Partial<P1 & P2 & P3 ... & P100>版本的東西。

我想避免如果可能需要大量的函數重載以支持這一點,因為我可以繼續編寫增加長度的Tupled版本。

我不能確定,因為我沒有安裝你正在使用的庫,但也許你可以這樣做:

type PfromSA<SA extends Array<ThemedStyleAugmentationFn<any, any>>>
  = { [K in keyof SA]: SA[K] extends ThemedStyleAugmentationFn<infer P, any> ? (x: P) => void : never } extends
  { [k: number]: (x: infer P) => void } ? P : never;

type SAExtendsTProperly<SA extends Array<ThemedStyleAugmentationFn<any, any>>, T>
  = { [K in keyof SA]: SA[K] extends ThemedStyleAugmentationFn<any, infer U> ? [U] extends [T] ? SA[K] : ThemedStyleAugmentationFn<any, T> : never }

export function multiAugment<
  SA extends Array<ThemedStyleAugmentationFn<any, any>>,
  C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
  T extends object,
  O extends object = {},
  A extends keyof any = never
>(
  styledComponent: StyledComponent<C, T, O, A>,
  ...styleAugmentations: SA & SAExtendsTProperly<SA, T>
): StyledComponent<C, T, O & Partial<PfromSA<SA>>, A> {
  const augmented = styled(styledComponent)`
    ${styleAugmentations}
  `;

  return augmented as StyledComponent<C, T, O & Partial<PfromSA<SA>>, A>;
}

你的想法是你為styleAugmentations參數使用一個通用的rest參數 (在上面的例子中,我把它作為一個rest參數而不是一個元組; TypeScript不會從數組文字中推斷出一個元組類型,但它會從中推斷出一個元組類型一個rest參數。如果你需要一個數組文字,你需要斷言或以其他方式哄騙編譯器將其解釋為一個元組。

此類型參數SAThemedStyleAugmentationFn<any, any>的數組。 然后類型函數PfromSA<SA> 在條件類型中使用類型推斷來計算SA所需的P類型的交集。 類型函數SAExtendsTProperly<SA>做了類似的事情,以確保每個元素的ThemedStyleAugmentationFn<P, TA>都有TA正確擴展T (因為ThemedStyleAugmentationFn<P, TA>TA可能是不變的,你不能只確保SA extends ThemedStyleAugmentationFn<any, T> ;你必須遍歷元組並獲取每個元素的TA )。

應該可以按你的需要工作,但是,如果沒有更多自包含的代碼,我無法確定。

希望對你有所幫助。 祝好運。

暫無
暫無

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

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