我玩周围的typescript,并试图创建一个脚本,将更新一个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>
还有迎宾员。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/ setter .ts(8,53):属性“value”在类型为“HTMLElement”的值上不存在
然而,编译器会输出一个javascript文件,这在chrome中工作得很好。
我怎么得到这个错误?我该怎么解决呢?
此外,我可以在哪里查找哪些属性是有效的“HTMLElement”根据typescript?
请注意,我对javascript和typescript很陌生,所以我可能会遗漏一些明显的东西。:)
根据Tomasz Nurkiewiczs的回答,“问题”是typescript是类型安全的。所以document.getElementById()返回不包含value属性的HTMLElement类型。子类型HTMLInputElement包含value属性。
因此,一个解决方案是将getElementById()的结果强制转换为HTMLInputElement,如下所示:
var inputValue = (<HTMLInputElement>document.getElementById(elementId)).value;
<>是typescript中的强制转换操作符。请参阅问题TypeScript: casting HTMLElement。
如果您在.tsx文件中,上面的强制转换语法将抛出错误。你会想要使用下面的语法:
(document.getElementById(elementId) as HTMLInputElement).value
上面这行代码的结果是这样的:
inputValue = (document.getElementById(elementId)).value;
即不包含类型信息。
问题就在这里:
document.getElementById(elementId).value
您知道从getElementById()返回的HTMLElement实际上是从它继承的HTMLInputElement的实例,因为您传递的是输入元素的ID。类似地,在静态类型的Java中,这不会编译:
public Object foo() {
return 42;
}
foo().signum();
signum()是Integer的一个方法,但编译器只知道foo()的静态类型,即Object。Object没有signum()方法。
但是编译器不能知道这一点,它只能基于静态类型,而不是代码的动态行为。据编译器所知,document.getElementById(elementId)表达式的类型没有value属性。只有输入元素才有价值。
对于参考检查HTMLElement和htmllinputelement在MDN。我猜Typescript或多或少和这些是一致的。
根据Tomasz Nurkiewiczs的回答,“问题”是typescript是类型安全的。所以document.getElementById()返回不包含value属性的HTMLElement类型。子类型HTMLInputElement包含value属性。
因此,一个解决方案是将getElementById()的结果强制转换为HTMLInputElement,如下所示:
var inputValue = (<HTMLInputElement>document.getElementById(elementId)).value;
<>是typescript中的强制转换操作符。请参阅问题TypeScript: casting HTMLElement。
如果您在.tsx文件中,上面的强制转换语法将抛出错误。你会想要使用下面的语法:
(document.getElementById(elementId) as HTMLInputElement).value
上面这行代码的结果是这样的:
inputValue = (document.getElementById(elementId)).value;
即不包含类型信息。