TS2339: “元素”类型上不存在“样式”属性

密码是这样的:

const test = Array.from(document.getElementsByClassName('mat-form-field-infix'));
test.forEach((element) => {
element.outerHTML = '<div class="good-day-today" style="width: 0px;"></div>'; // Please note that this line works fine!
element.style.padding = '10px';
element.style.borderTop = '0';
});

编译时出现的错误:

Src/app/< em >/ .Component. ts (101,21)中的错误: ERROR TS2339: Property 类型“ Element”上不存在“ style”。 Src/app/< em >/ .Component. ts (102,21) : error TS2339: Property‘ style’(102,21) : 错误 TS2339: 属性‘ style’ 类型“ Element”上不存在。

我该怎么补救?

我尝试去除 Array.from...的部分,尝试使用 for offor in,尝试 as any,但以上是我必须做到这一点的方式。

128223 次浏览

你需要定型:

Array.from(document.getElementsByClassName('mat-form-field-infix') as HTMLCollectionOf<HTMLElement>)

这是因为 getElementsByClassName 只有回报 HTMLCollection<Element>Element没有 style属性。HTMLElement然而 确实实施了通过它的 ElementCSSInlineStyle扩展接口。

注意,这种类型转换是类型安全的,每个 Element都是 HTMLElementSVGElement,我希望您的 SVG 元素没有类。

设置 outHTML 时,会破坏原来存在的元素,因此样式不起作用。

您会注意到,如果将其更改为设置 innerHTML,则样式 是的可以正常工作。

这并不完全相同,但我希望它能为你指明正确的方向。

const test = Array.from(document.getElementsByClassName('mat-form-field-infix'));
test.forEach((element) => {
element.innerHTML = '<div class="good-day-today" style="width: 0px;"></div>'; // Please note that this line works fine!
element.style.padding = '10px';
element.style.borderTop = '0';
});

另一种选择是使用 querySelectorAll和类型参数。getElementsByClassName不是通用的,但是 querySelectorAll是-你可以只传递要选择的元素的类型,像这样:

const test = document.querySelectorAll<HTMLElement>('.mat-form-field-infix');

这不需要任何类型强制转换,还有将允许您立即使用 forEach,而不是先将其转换为数组。(getElementsByClassName返回一个 HTMLCollection,它没有 forEach方法; querySelectorAll返回一个 NodeList,而 是的有一个 forEach方法,至少在某种程度上是最新的浏览器。为了支持古老的浏览器,你需要一个 填料,或者首先把它转换成一个数组。)

如果您碰巧只需要一个元素,您可以使用 querySelector,它也是通用的:

const elm = document.querySelector<HTMLElement>('.foo')!;
elm.style.padding = '10px';

与许多其他选项相比,querySelectorAll(和 querySelector)的另一个好处是它们接受 CSS 选择器字符串,这可以更加灵活和精确。例如,选择器字符串

.container > input:checked

将选择子 <div class="container"><input>和被检查。

我也面临着类似的问题

document.querySelectorAll(".<className>");

因此,我没有添加 style 属性,而是简单地通过添加另一个类来绕过它。

例如:

//css file
.<classname> {
display: none;
}
.<classname>.show {
display: flex;
}


//ts file
elements.forEach((ele, index) => {
const errors = something.length;
if (index < errors) {
ele.classList.add("show");
} else {
ele.classList.remove("show");
}

};

变通方法可以是这样的:

element["style"].padding = '10px';
element["style"].borderTop = '0';

也许这不是最好的解决方案,但它应该工作,我使用了多次:)

我想我找到了一个更简单的方法:

只需创建一个 index.d.ts 文件并添加:

interface Element {
style: CSSStyleDeclaration
}

也许这个能帮上忙:

let element = <HTMLElement> document.getElementsByClassName(className)[0];

乔纳斯威尔姆斯的 回答不是完全正确的(不再?)。

虽然我怀疑类型转换在这种情况下不会导致任何问题,但我仍然尽可能避免类型转换。在这种情况下,可以避免使用 缩小范围的实例进行类型强制转换:

const test = Array.from(
document.getElementsByClassName('mat-form-field-infix')
)
test.forEach((element) => {
if (!(element instanceof HTMLElement)) {
return
}


element.outerHTML =
'<div class="good-day-today" style="width: 0px;"></div>' // Please note that this line works fine!
element.style.padding = '10px'
element.style.borderTop = '0'
})