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

新手上路,请多包涵

我正在玩打字稿,并试图创建一个脚本,该脚本将在输入框中输入文本时更新 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 非常陌生,所以我可能会遗漏一些明显的东西。 :)

原文由 Bjarke Freund-Hansen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3k
2 个回答

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

因此,解决方案是将 getElementById() 的结果转换为 HTMLInputElement 如下所示:

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

<> 是打字稿中的铸造运算符。请参阅问题 TypeScript:casting HTMLElement

如果您在 .tsx 文件中,上面的转换语法将引发错误。您将希望改用此语法:

 (document.getElementById(elementId) as HTMLInputElement).value

上面一行生成的 javascript 如下所示:

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

即不包含类型信息。

原文由 Bjarke Freund-Hansen 发布,翻译遵循 CC BY-SA 4.0 许可协议

我的原始代码:

 <ion-input
  type="number"
  value={{propertyValue}}
  (change)="propertyValue = $event.target.value"
></ion-input>

使我的编辑器显示以下错误:

 Property 'value' does not exist on type 'EventTarget'. ngtsc(2339)

不幸的是,我发现在模板中解决这个问题的唯一方法是使用 $any()

我同意这个关于 touchmarine回答,他主张使用 类型保护 而不是类型断言。

我想在回调中直接使用 valuevalue got typed as string | number which may be correct but but this.propertyValue is number so I still can not set it directly:

 (property) Components.IonInput["value"]?: string | number

使用 instanceof 就像在提到的答案中使用 number 这样的错误:

 TS2693: 'number' only refers to a type, but is being used as a value here.

使用 Number 这样的错误(注意大写字母 N):

 TS2322: Type 'Number' is not assignable to type 'number'.


解决方案

  • 不推荐铸造类型
  • 我们需要一个回调,因为模板不支持这个
  • #id 选择器是当今从 Angular 中的元素获取值的首选方式。它在那里的大部分时间都在打字。
  • instanceof 不适用于原语,因此我们使用 typeof
 <ion-input
  type="number"
  value={{propertyValue}}
  #propertyValueInput
  (change)="setPropertyValue(propertyValueInput.value)"
></ion-input>

 public setPropertyValue (value) {
  if (typeof value === 'number') {this.propertyValue = value}
}

最后!我们是类型安全且无错误的! 🎉🎉🎉

PS 这还有一个额外的好处,就是如果输入了除数字以外的任何其他内容,则忽略用户输入。例如,在浏览器中,我也可以在该输入字段中键入字母。

更多信息供参考: 为什么 TypeScript 中的 ‘instanceof’ 会给我错误“’Foo’ 仅指一种类型,但在这里被用作值。”?

原文由 ThaJay 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进