我正在使用JSS,并且希望定义一个style
对象,该对象同时具有强类型键和值,而不需要定义两次键。
首次尝试:
const style: Record<string, CSSProperties> = {
root: {
background: 'red'
},
title: {
fontWeight: 'bold'
},
...
}
现在style
不是强类型的,所以编译器在访问style.nonExistingKey
时不会给出警告。
第二次尝试:
如果我像这样显式地指定键:
const style: Record<'root' | 'title' | ... , CSSProperties> = {
root: {
background: 'red'
},
...
}
然后我得到一个强类型的Record,即style.nonExistingKey
将抛出一个错误。但是,这个方法需要复制记录键,因为它们必须作为泛型参数显式添加。
第三次尝试:
我可以使用下面的代码在事后创建一个强类型的Record:
const styleObj = {
root: {
background: 'red'
},
title: {
fontWeight: 'bold'
},
...
}
const style = styleObj as Record<keyof typeof styleObj, CSSProperties>
但是,这样就无法对记录的CSSProperties
值进行类型检查,因此这不是一个好的解决方案。
有没有办法做这样的事情
const style: Record<T, CssProperties> = {
root: {
background: 'red'
},
...
}
并将T
自动推断为'root' | 'title' | ...
等?
4条答案
按热度按时间x7rlezfr1#
在定义对象时,可以使用帮助器函数。该函数将具有类型参数,该参数要求所有属性必须是使用索引签名的
CSSProperties
类型。由于该函数是泛型的,因此将正确键入结果(它实际上没有索引签名,而只有定义的属性)您也可以键入它来返回
Record
,但我不认为这会增加任何值cld4siwp2#
更新
在学习了更多的TypeScript之后,我设法让它在一个函数中工作。所以这里是新的,简短的和有效的解决方案。
帮助函数:
组件示例:
crcmnpdw3#
[x in keyof y]
就能解决这个问题:删除
?
以使所有字段都是必填字段。elcex8rz4#
对于TypeScript 4.9,我认为这最终可以通过使用新的
satisfies
操作符来实现:运动场
如上面的示例所示,这将保留对象中所有键和值的强类型,并防止添加不满足类型的属性。