类型“ HTMLElement”的值不存在属性“值”


235

我正在玩打字稿,正在尝试创建一个脚本,当在输入框中输入文本时,该脚本将更新p元素。

html如下所示:

<html>
    <head>
    </head>
    <body>
        <p id="greet"></p>
        <form>
            <input id="name" type="text" name="name" value="" onkeyup="greet('name')" />
        </form>
    </body>
    <script src="greeter.js"></script>
</html>

greeter.ts文件:

function greeter(person)
{
    return "Hello, " + person;
}

function greet(elementId)
{
    var inputValue = document.getElementById(elementId).value;

    if (inputValue.trim() == "")
        inputValue = "World";

    document.getElementById("greet").innerText = greeter(inputValue);
}

当我进行编译时,tsc出现以下“错误”:

/home/bjarkef/sandbox/greeter.ts(8,53): The property 'value' does not exist on value of type 'HTMLElement'

但是,编译器会输出一个javascript文件,该文件在chrome中可以正常工作。

我怎么会得到这个错误?我该如何解决?

另外,在哪里可以'HTMLElement'根据打字稿查找哪些属性有效?

请注意,我对javascript和Typescript还是很陌生,所以我可能缺少明显的东西。:)

Answers:


448

根据Tomasz Nurkiewiczs的答案,“问题”是打字稿是类型安全的。:)因此,document.getElementById()返回的类型HTMLElement不包含value属性。HTMLInputElement但是,子类型确实包含该value属性。

因此,一个解决方案是投的结果getElementById(),以HTMLInputElement这样的:

var inputValue = (<HTMLInputElement>document.getElementById(elementId)).value;

<>是打字稿中的转换运算符。请参阅问题TypeScript:强制转换HTMLElement

从上一行得到的javascript如下所示:

inputValue = (document.getElementById(elementId)).value;

即不包含类型信息。


您有没有列出html的哪个元素属于打字稿类型的列表?如果是的话请张贴将对某人有帮助!感谢您的出色回答。
Pardeep Jain

1
此修复程序完全破坏了我的代码;说接下来发生的事情“不是功能”。我不了解TS处理此问题的原因。由于getElementById可以返回任何元素类型,因此默认情况下应接受任何元素类型。
乌龟很可爱

@TurtlesAreCute我很好奇这个解决方案如何破坏您的代码。希望一年后您找到了一个解决方案,但是强制转换为HTMLInputElement应该可以。
米歇尔·波拉

就我而言,我不得不将其更改为HTMLAnchorElement。
野蛮锤

@Wildhammer因为您的元素不是 Input元素!OP是。
-Auspex

68

如果您使用反应,则可以使用as运算符。

let inputValue = (document.getElementById(elementId) as HTMLInputElement).value;

3
由于某种原因,这里接受的答案对我提出了以下错误:JSX元素“ HTMLInputElement”没有相应的结束标记。这是对我有用的答案。
NigelTufnel

1
原因是因为在tsx文件中您不能使用<>运算符进行转换,因为这些运算符在React中使用。因此,您必须使用:basarat.gitbooks.io/typescript/docs/types/…–
Powderham

尽管这对我没有用,但确实为我指明了正确的方向:)投上票!!!
西蒙·普莱斯

40

尝试将要更新的元素转换为HTMLInputElement。如其他答案所述,您需要向编译器提示这是HTMLElement的特定类型:

var inputElement = <HTMLInputElement>document.getElementById('greet');
inputElement.value = greeter(inputValue);


17

快速解决方法是使用[]选择属性。

function greet(elementId) {
    var inputValue = document.getElementById(elementId)["value"];
    if(inputValue.trim() == "") {
        inputValue = "World";
    }
    document.getElementById("greet").innerText = greeter(inputValue);
}

我只是尝试了几种方法并找到了解决方案,
我不知道您的原始脚本背后的问题是什么。

作为参考,您可以参考Tomasz Nurkiewicz的帖子。


正确回答问题,对我帮助很大。
Monir Khan,

15

问题在这里:

document.getElementById(elementId).value

您知道HTMLElement返回自getElementById()实际上是HTMLInputElement从其继承的实例,因为您正在传递输入元素的ID。同样,在静态类型的Java中,它不会编译:

public Object foo() {
  return 42;
}

foo().signum();

signum()是的一种方法Integer,但是编译器只知道的静态类型foo(),即Object。而且Object没有signum()方法。

但是编译器不知道,它只能基于静态类型,而不能基于代码的动态行为。而且据编译器所知,document.getElementById(elementId)表达式的类型没有value属性。只有输入元素才有价值。

对于参考检查HTMLElementHTMLInputElement在MDN。我猜打字稿或多或少与这些一致。


但是我没有.value在p元素上访问,而是在input元素上访问它。还是我弄错了?
Bjarke Freund-Hansen '10 -10-20

1
@bjarkef:您正在打电话document.getElementById("greet"),您有<p id="greet"></p>...
Tomasz Nurkiewicz 2012年

我正在调用document.getElementById("greet").innerText哪个应该是完全有效的,我只value在输入元素的包含以下内容的行中访问输入元素的属性:var inputValue = document.getElementById(elementId).value;in greet(elementId)和that在html onkeyup="greet('name')"中以输入形式调用。因此,我认为您误读了代码,如果我错了,请纠正我。:)
Bjarke Freund-Hansen 2012年

@bjarkef:对不起,你是对的。我已经重写了答案,看看吧!
Tomasz Nurkiewicz 2012年

1
嗯,这很有道理。那么我应该转换从中返回的值getElementById,如何在打字稿中进行转换呢?还是有另一个方法getElementById可以返回HTMLInputElement
Bjarke Freund-Hansen '10 -10-20

11

对于使用属性(例如“道具”或“参考”)但没有“ DocgetId”的任何人,您也可以:

("" as HTMLInputElement).value;

反引号是您的props值,因此示例如下所示:

var val = (this.refs.newText as HTMLInputElement).value;
alert("Saving this:" + val);



-1

问题:

错误类型“ HTMLElement”上不存在属性“文本”

解决方案:在打字稿我们需要铸造document.getElementById()返回类型HTMLElement< HTMLScriptElement >

因此,我们可以通过以下方法来解决此问题,以解决typescript.js预期的错误

Code: var content: string = ( < HTMLScriptElement > document.getElementById(contentId)).text;

它对我有用..希望它也对您有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.