typescript - HTMLElement 作为由 tagName 区分的联合
问题描述
我想让 TypeScript 知道,当我打开一个元素tagName
并且案例是“输入”时,案例代码中的元素就是一个输入元素。我知道原则上可以使用可区分联合,但显然类型都不Element
是HTMLElement
可区分联合,因此以下代码失败:
function foo(e : HTMLElement) {
switch(e.tagName) {
case 'input':
e.value = '123'; // Property 'value' does not exist on type 'HTMLElement'.
break;
case 'a':
e.href = 'hi'; // Property 'href' does not exist on type 'HTMLElement'.
break;
}
}
因此,作为一种快速解决方法,我可以这样做:
interface TaggedLink extends HTMLLinkElement {
tagName: 'a'
}
interface TaggedInput extends HTMLInputElement {
tagName: 'input'
}
type TaggedHTMLElement = TaggedLink | TaggedInput;
function foo(e : TaggedHTMLElement) {
switch(e.tagName) {
case 'input':
e.value = '123'; // Good
break;
case 'a':
e.href = 'hi'; // Good
break;
}
}
这行得通,但现在每个打电话的人foo
都必须将参数转换为TaggedHTMLElement
.
所以我想知道 TypeScript 是否已经带有一个元素作为可区分联合类型,我可以直接将其用作 foo 的参数类型,开箱即用,或者是否有更好的方法来做我正在尝试的事情至。我知道有一个名为的类型HTMLElementTagNameMap
似乎很有用,但我认为我需要能够重新定义HTMLElement
(类似于interface HTMLElement extends actual HTMLElement
),以及某种方式来循环所有类型HTMLElementTagNameMap
以生成类似于我定义的类型上面,然后将它们全部合并。但似乎这些事情都不可能发生。
解决方案
HTMLElement
并且Element
已经有tagName
属性,它是只读的,只是一个string
.
如果您想确切地知道哪个元素是,您必须对元素实例进行运行时检查。
function foo(e : HTMLLinkElement | HTMLInputElement) {
if (e instanceof HTMLInputElement) {
e.value = '123';
}
else if (e instanceof HTMLLinkElement) {
e.href = 'hi';
}
}
const el = document.querySelector<HTMLLinkElement>("a")
if (el) {
foo(el)
}
``
推荐阅读
- javascript - 使用 TypeScript 的 Blazor WebAssembly 存在运行时错误
- javascript - 检查数组中对象的属性是否包含在另一个对象数组中
- flutter - json数据flutter中搜索栏的实现
- python - 无法加载我刚刚创建的 JSON 文件(json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0))
- geopandas - 在 geopandas 的 LINESTRING Z 中访问 Z 坐标?
- postgresql - 模拟可空列的主键
- jquery - Validate and Post file using Jquery, PHP
- javascript - 将 2 个对象数组组合成 1 个对象数组(重构请求)
- docker - 如何将 Windows 应用程序连接到 Docker 网络?
- python - 带有自动完成功能的风筝问题的原子。未显示函数签名