我有一個名為 的函式myStyles,它接受一個引數。這個引數是一個包含一個baseStyles物件和一個styleVariants物件的物件。它只是回傳styleVariants物件。
function myStyles<StyleVariants extends StyleVariantsStructure>(params: {
baseStyles: AllowedStyles;
styleVariants: StyleVariants;
}): StyleVariants {
return params.styleVariants;
}
它是這樣呼叫的:
myStyles({
baseStyles: {
color: 'red',
backgroundColor: 'red',
},
styleVariants: {
color: {
red: {
color: 'red',
backgroundColor: 'red',
},
},
},
});
該baseStyles物件具有 type AllowedStyles,它決定了我們允許使用哪些 css 屬性和值。這很完美,如果呼叫myStyles函式時 CSS 屬性或值拼寫錯誤,我們會得到正確的 TS 錯誤,例如
type AllowedStyles = {
color?: 'red';
backgroundColor?: 'red';
};
該styleVariants物件的型別為StyleVariantsStructure。這實質上決定了它應該接受一個或多個包含AllowedStyleseg 的嵌套物件
type StyleVariantsStructure = {
[k: string]: {
[k: string]: AllowedStyles;
};
};
在myStyles函式中,我們對styleVariantsparam 物件使用型別推斷。意思是,我們會自動獲取styleVariants傳入myStyles函式的確切型別。然后我們使用該styleVariants型別作為函式的回傳型別。這對我們來說是必需的,因為我們需要知道myStyles. 這是我們的功能:
function myStyles<StyleVariants extends StyleVariantsStructure>(params: {
baseStyles: AllowedStyles;
styleVariants: StyleVariants;
}): StyleVariants {
return params.styleVariants;
}
這是型別推斷回傳型別的示例,取自
問題
As you can see, I need to both restrict things being passed in the styleVariants object, using the StyleVariantsStructure type e.g. we must only accept AllowedStyles. However, we also need to use the inferred type from styleVariants for the return type of the myStyles function. I have attempted to solve this by using StyleVariants extends StyleVariantsStructure. This works somewhat, but some Typescript errors aren't highlighted in the styleVariants argument object when calling myStyles.
For example, if color is misspelled, we get no TS error:

However, I do get type suggestions:

And, I do get errors if the value is misspelled:

Essentially, to me, it seems like I need to find an alternate way to use type inference for the styleVariants object, whilst also restricting it using the StyleVariantsStructure type. Any help on this would be much appreciated.
Typescript 操場中問題的最小演示
uj5u.com熱心網友回復:
嚴格來說,這看起來是正確的,但需要哄著 TS 去檢查它。例如,使用 console.log() 將呼叫包裝在 Playground 中會生成您想要的型別檢查。
TS 作為檢查器并不完美,因此在高度復雜的情況下它可能需要一些技巧才能檢測到“正確”的解決方案 - 這就是!
uj5u.com熱心網友回復:
問題似乎更像是 Typescript 的限制。我發現的一種解決方法,對我們來說是一個完整的解決方案,如下所示:
function myStyles<StyleVariants>(params: {
baseStyles: AllowedStyles;
styleVariantKeys: StyleVariants;
styleVariants: StyleVariantsStructure;
}): StyleVariants {
return params.styleVariantKeys;
}
- 將
styleVariantsKey物件添加到myStyles函式引數 - 從中推斷型別
- 給
styleVariants該StyleVariantsStructure型別
這允許您按預期進行型別檢查,并允許您從styleVariantsKey. 但是當然這意味著你必須有兩個相同的物件,在我們的例子中這不是什么大問題,因為我們實際上不需要由 回傳的嵌套樣式物件myStyles,只需要變體名稱。所以我們的函式呼叫看起來像這樣:
myStyles({
baseStyles: {
color: 'red',
backgroundColor: 'red',
},
styleVariantKeys: {
color: ["red"],
},
styleVariants: {
color: {
red: {
color: 'red',
backgroundColor: 'red',
},
},
},
});
uj5u.com熱心網友回復:
所以,我花在它上面的時間比我預期的要多,但我們來了。如果您需要突出顯示錯別字,您應該基于 AllowedStyles 的 StyleVariants,例如:
type AllowedStyles = {
color: 'red' | 'green';
backgroundColor: 'red';
};
type StyleVariants = {
[K in keyof AllowedStyles]?: AllowedStyles[K] | Partial<Record<AllowedStyles[K], Partial<AllowedStyles>>>
}
type StyleVariantsStructure = {
baseStyles: AllowedStyles
styleVariants: StyleVariants
}
function myStyles(params: StyleVariantsStructure):StyleVariants {
return params.styleVariants;
}
StyleVariants 基于 AllowedStyles 結構和值,它包含 AllowedStyles 的所有屬性,但它們是可選的。每個屬性的型別分別在 AllowedStyles 型別的屬性中提供,或者它是一個物件,其鍵是 AllowedStyles 中每個提供的型別到屬性,其型別再次是 AllowedStyles,所有屬性都是可選的。希望你能明白!
打字稿游樂場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311138.html
上一篇:如何在C#中撰寫帶有變數類的函式
下一篇:帶記錄的泛型佇列,直接入隊記錄
