349

我正在玩打字稿,并试图创建一个脚本,该脚本将在输入框中输入文本时更新 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'另外,我在哪里可以根据打字稿查找哪些属性在 a 上有效?

请注意,我对 javascript 和 typescript 非常陌生,所以我可能会遗漏一些明显的东西。:)

4

15 回答 15

588

根据 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;

即不包含类型信息。

于 2012-10-20T15:58:38.753 回答
123

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

let inputValue = (document.getElementById(elementId) as HTMLInputElement).value;
于 2017-05-06T18:06:20.427 回答
47

我们可以 断言

const inputElement: HTMLInputElement = document.getElementById('greet')

或使用as-syntax

const inputElement = document.getElementById('greet') as HTMLInputElement

给予

const inputValue = inputElement.value // now inferred to be string
于 2018-09-25T09:50:04.923 回答
45

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

var inputElement = <HTMLInputElement>document.getElementById('greet');
inputElement.value = greeter(inputValue);
于 2012-10-20T15:54:38.723 回答
23

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

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

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

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

于 2012-10-20T15:46:38.337 回答
20

问题在这里:

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属性。只有输入元素才有价值。

对于参考检查HTMLElementHTMLInputElementMDN。我猜 Typescript 或多或少与这些一致。

于 2012-10-20T15:17:41.290 回答
14

同样对于使用 Props 或 Refs 等属性但没有您的“DocgetId”的任何人,您可以:

("" as HTMLInputElement).value;

倒引号是您的道具值,因此示例如下:

var val = (this.refs.newText as HTMLInputElement).value;
alert("Saving this:" + val);
于 2018-01-09T09:26:12.553 回答
14

对于那些可能仍在为此苦苦挣扎的人,另一种选择是使用(document.getElementById(elementId) as HTMLInputElement).value = ''. 来源

如果您仍然遇到问题,请尝试将其提取到如下函数:

function myInput() {
   (document.getElementById(elementId) as HTMLInputElement).value = ''
}
于 2021-05-03T16:08:36.663 回答
7

如果您使用的是角度,您可以使用 -

const element = document.getElementById('elemId') as HTMLInputElement;
于 2019-09-17T09:02:56.793 回答
6

有一种方法可以在使用类型断言的情况下实现这一点,而是使用泛型,这通常使用起来更好更安全。

不幸的是,getElementById不是通用的,而是querySelector

const inputValue = document.querySelector<HTMLInputElement>('#greet')!.value;

类似地,您可以使用querySelectorAll来选择多个元素并使用泛型,以便 TS 可以理解所有选择的元素都属于特定类型:

const inputs = document.querySelectorAll<HTMLInputElement>('.my-input');

这将产生一个NodeListOf<HTMLInputElement>.

于 2021-01-09T19:03:33.937 回答
1

这对我有用:

let inputValue = (swal.getPopup().querySelector('#inputValue ')as HTMLInputElement).value
于 2019-11-04T18:40:18.367 回答
1

我一直有一个类似的问题(JS文件中的TS警告:“类型X上不存在属性X”:是否可以编写更干净的JavaScript?

虽然该标记有助于删除 typescript 文件中的警告,但编译后我的 JavaScript 文件中仍然会收到警告。

那么如何编写干净且允许我操作 .value 的代码呢?

我花了很长时间,但我通过使用另一种方法找到了解决方案:

HTML 代码:

<form id="my-form" 
   action="index.html"
   method="get"
   onsubmit="return showValue();">
    <input type="text" name="username">
    <input type="text" name="full-name">
    <input type="password" name="password">
    <button type="button" onclick="showValue();">Show value</button>
</form>

Javascript代码:

function showValue() {
    const myForm = document.forms.my-form;
    console.log(myForm?.username.value);
    return 1;
}

document.forms.x一个属性"value",可以删除打字稿文件和生成的 JavaScript 中的警告。

于 2021-10-12T10:03:39.680 回答
0

这可能看起来很陈词滥调,但这对我有用:

yarn add -D @types/web

我想我一定有一个过时的类型定义。

于 2021-09-24T21:10:29.967 回答
0

如果您有需要分配动态值的动态元素 ID,则可以使用:

//element_id = you dynamic id.
//dynamic_val = you dynamic value.
let _el = document.getElementById(element_id);
_el.value = dynamic_val.toString();

这对我有用。

于 2020-08-02T15:11:06.513 回答
-2

问题:

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

解决方案:在 typeScript中我们需要强制转换document.getElementById()返回类型HTMLElement< HTMLScriptElement >

所以我们可以通过以下方式来解决typescript.js预期的错误

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

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

于 2015-08-18T06:25:56.420 回答