[英]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參數。如果你需要一個數組文字,你需要斷言或以其他方式哄騙編譯器將其解釋為一個元組。
此類型參數SA
是ThemedStyleAugmentationFn<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.