[英]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.