![](/img/trans.png)
[英]Linting errors for ref()'s within Vue 3 templates when using setup with TypeScript <setup lang="ts" script>
[英]Typescript Bug: Extending An Inferred Type Prevents TS Linting Errors (Playground Example Provided)
我有一個名為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
對象的類型為AllowedStyles
,它決定了我們允許使用哪些 css 屬性和值。 這很完美,如果在調用myStyles
函數時 CSS 屬性或值拼寫錯誤,我們會得到正確的 TS 錯誤,例如
type AllowedStyles = {
color?: 'red';
backgroundColor?: 'red';
};
styleVariants
對象的類型為StyleVariantsStructure
。 這實質上決定了它應該接受一個或多個包含AllowedStyles
嵌套對象,例如
type StyleVariantsStructure = {
[k: string]: {
[k: string]: AllowedStyles;
};
};
在myStyles
函數中,我們對styleVariants
參數對象使用類型推斷。 這意味着,我們會自動獲取傳遞給myStyles
函數的styleVariants
的確切類型。 然后我們使用styleVariants
類型作為函數的返回類型。 這對我們來說是必需的,因為我們需要知道myStyles
的確切返回類型。 這是我們的功能:
function myStyles<StyleVariants extends StyleVariantsStructure>(params: {
baseStyles: AllowedStyles;
styleVariants: StyleVariants;
}): StyleVariants {
return params.styleVariants;
}
這是類型推斷返回類型的示例,取自我用來演示此問題的Typescript 游樂場:
問題
如您所見,我需要使用StyleVariantsStructure
類型來限制在styleVariants
對象中傳遞的styleVariants
,例如我們必須只接受AllowedStyles
。 但是,我們還需要使用從styleVariants
推斷出的類型作為myStyles
函數的返回類型。 我試圖通過使用StyleVariants extends StyleVariantsStructure
來解決這個StyleVariants extends StyleVariantsStructure
。 這在一定程度上起作用,但是在調用myStyles
時, styleVariants
參數對象中未突出顯示某些 Typescript 錯誤。
例如,如果color
拼寫錯誤,我們不會得到 TS 錯誤:
但是,我確實得到了類型建議:
而且,如果值拼寫錯誤,我確實會收到錯誤消息:
本質上,對我來說,似乎我需要找到一種替代方法來對styleVariants
對象使用類型推斷,同時還使用StyleVariantsStructure
類型對其進行限制。 對此的任何幫助將不勝感激。
嚴格來說,這看起來是正確的,但需要哄着 TS 去檢查它。 例如,使用 console.log() 將調用包裝在 Playground 中會生成您想要的類型檢查。
TS 作為檢查器並不完美,因此在高度復雜的情況下它可能需要一些技巧才能檢測到“正確”的解決方案 - 這就是!
問題似乎更像是 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',
},
},
},
});
所以,我花在它上面的時間比我預期的要多,但我們來了。 如果您需要突出顯示錯別字,您應該基於 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,所有屬性都是可選的。 希望你能明白!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.