typescript - 部分的联合类型和字典导致打字问题没有隐含的任何标志
问题描述
由于可以使用 VueJSv-bind:style
绑定设置 CSS 变量,我正在尝试创建一个联合类型,其中传递给v-bind:style
的对象保留类型,CssStyleDelcaration
但足够宽松以接受任意属性名称:
type Dictionary<T> = { [key: string]: T };
type Nullable<T> = T | null;
type CssStyleObject =
Partial<CSSStyleDeclaration> |
Dictionary<Nullable<string>>;
一个实现的例子是这样的(参见 TypeScript playground 上的实时代码):
<!-- Template -->
<div v-bind:style="myStyle"></div>
// Component code
@Component
export default class MyComponent extends Vue {
public get myStyle(): CssStyleObject {
const style: CssStyleObject = { };
style.backgroundColor = 'red';
style['--my-custom-css-property'] = '16px';
}
}
但是,当我noImplicitAny
启用标志时出现类型错误(由于项目范围的配置,我无法关闭该标志),因为 TypeScript 然后抱怨:
元素隐式具有“任何”类型,因为类型“CssStyleObject”没有索引签名。
我在这里看到了一个建议的解决方案:在启用 noImplicitAny 标志编译打字稿时,如何防止错误“对象类型的索引签名隐含地具有'任何'类型”?any
,但如果有其他可行的解决方案,我希望避免简单地转换为。
有趣的是,一旦我在分配给style
变量时使用自定义属性名称,错误消息就会消失:
const style: CssStyleObject = {
'--foobar': '50%'
};
style.backgroundColor = 'red';
style['--my-custom-css-property'] = '16px';
请参阅上面 TypeScript Playground 上的代码。
我怀疑这是因为 for 的类型style
随后以某种方式被修改为简单Dictionary<string>
而不是 union 类型,因此不会引发进一步的错误。
更新和解决方案
所以,事实证明,我天生就混淆了 TypeScript 中的交集和联合类型。在这种情况下,是和CssStyleObject
的交集,所以这就足够了:Partial<CSSStyleDeclaration>
Dictionary<Nullable<string>>
type Dictionary<T> = { [key: string]: T };
type Nullable<T> = T | null;
// Use `&` for creating an intersection type!
type CssStyleObject =
Partial<CSSStyleDeclaration> &
Dictionary<Nullable<string>>;
解决方案
首先,您的代码的当前行为是因为区分联合类型的工作方式。CSSStyleDeclaration
Dictionary 没有索引签名。因此,当您在声明中添加自定义属性时,类型被推断为Dictionary
.
其次,如果要向现有类型添加索引,则不应使用联合类型。您应该改用交集类型。也就是说,CssStyleObject
是一个CSSStyleDeclaration
并且有一个索引签名,但不是一个要么是要么CssStyleObject
有索引签名的对象
最后,这是工作代码
type CssStyleObject = Partial<CSSStyleDeclaration> & Record<string, string | null>
// or
interface CssStyleObject extends Partial<CSSStyleDeclaration> {
[key: string]: string | null
}
推荐阅读
- docker - docker 图像按标签选择,带有 NOT 逻辑
- swift - 在 Swift 中,处理 html 字符串的块进入无限循环并导致应用程序中断
- powerquery - 将列表展开到 Power Query 中的同一行
- python - 如何实现矢量的移动?
- macos - 如何在 Jupyter 实验室、MacBook M1 中使用 Julia?
- tensorflow - tensorflow TypeError:ParseFromString() 缺少 1 个必需的位置参数:“序列化”
- javascript - Anychart 极坐标线表现
- python - 计算组内值的比例
- pdf - iText7 延迟签名的 pdf 文档显示“自应用签名以来文档已被更改或损坏”
- python-3.x - 如何将具有相同属性的图像保存为不同的图像