Spo*_*man 183 typescript
有谁知道如何使用TypeScript进行投射?
我正在尝试这样做:
var script:HTMLScriptElement = document.getElementsByName("script")[0];
alert(script.type);
Run Code Online (Sandbox Code Playgroud)
但它给了我一个错误:
Cannot convert 'Node' to 'HTMLScriptElement': Type 'Node' is missing property 'defer' from type 'HTMLScriptElement'
(elementName: string) => NodeList
Run Code Online (Sandbox Code Playgroud)
除非我将它转换为正确的类型,否则我无法访问脚本元素的'type'成员,但我不知道如何执行此操作.我搜索了文档和样本,但我找不到任何东西.
Spo*_*man 242
TypeScript使用'<>'来包围强制转换,因此上面变为:
var script = <HTMLScriptElement>document.getElementsByName("script")[0];
Run Code Online (Sandbox Code Playgroud)
但是,遗憾的是你做不到:
var script = (<HTMLScriptElement[]>document.getElementsByName(id))[0];
Run Code Online (Sandbox Code Playgroud)
你得到错误
Cannot convert 'NodeList' to 'HTMLScriptElement[]'
Run Code Online (Sandbox Code Playgroud)
但你可以这样做:
(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Run Code Online (Sandbox Code Playgroud)
Fen*_*ton 36
从TypeScript 0.9开始,该lib.d.ts文件使用专门的重载签名,返回正确的调用类型getElementsByTagName.
这意味着您不再需要使用类型断言来更改类型:
// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
Run Code Online (Sandbox Code Playgroud)
Jac*_*128 21
您始终可以使用以下方式破解类型系统:
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Run Code Online (Sandbox Code Playgroud)
Ben*_* B. 18
不要输入演员表.决不.使用型号防护装置:
const e = document.getElementsByName("script")[0];
if (!(e instanceof HTMLScriptElement))
throw new Error(`Expected e to be an HTMLScriptElement, was ${e && e.constructor && e.constructor.name || e}`);
// locally TypeScript now types e as an HTMLScriptElement, same as if you casted it.
Run Code Online (Sandbox Code Playgroud)
让编译器为您完成工作,并在您的假设错误时获取错误.
在这种情况下,它可能看起来有些过分,但如果你稍后再回来并改变选择器,它会帮助你很多,比如添加一个dom中缺少的类.
Cer*_*nce 14
一个更优雅的解决方案是使用泛型来指示您选择的元素的类型,而不是使用类型断言、类型保护或any解决该问题。
不幸的是,getElementsByName它不是通用的,但是querySelector并且querySelectorAll是。(querySelector而且querySelectorAll也更加灵活,因此在大多数情况下可能更可取。)
如果您将标签名称单独传递到querySelector或中querySelectorAll,则由于 中的以下行,它将自动正确键入lib.dom.d.ts:
querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
Run Code Online (Sandbox Code Playgroud)
例如,要选择页面上的第一个脚本标记(如您的问题所示),您可以执行以下操作:
const script = document.querySelector('script')!;
Run Code Online (Sandbox Code Playgroud)
就是这样 - TypeScript 现在可以推断出现script在是一个HTMLScriptElement.
querySelector当您需要选择单个元素时使用。如果需要选择多个元素,请使用querySelectorAll。例如:
document.querySelectorAll('script')
Run Code Online (Sandbox Code Playgroud)
结果为NodeListOf<HTMLScriptElement>.
如果您需要更复杂的选择器,可以传递类型参数来指示要选择的元素的类型。例如:
const ageInput = document.querySelector<HTMLInputElement>('form input[name="age"]')!;
Run Code Online (Sandbox Code Playgroud)
结果被ageInput键入为HTMLInputElement.
Joh*_*rug 12
最终得到:
Array对象(不是NodeList打扮成一个Array)HTMLElements,而不是Node强制转换为HTMLElements试试这个:
let nodeList : NodeList = document.getElementsByTagName('script');
let elementList : Array<HTMLElement> = [];
if (nodeList) {
for (let i = 0; i < nodeList.length; i++) {
let node : Node = nodeList[i];
// Make sure it's really an Element
if (node.nodeType == Node.ELEMENT_NODE) {
elementList.push(node as HTMLElement);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请享用.
只是为了澄清,这是正确的.
无法将'NodeList'转换为'HTMLScriptElement []'
作为NodeList不是实际的阵列(例如它不包含.forEach,.slice,.push,等等).
因此,如果它确实转换为HTMLScriptElement[]类型系统,如果您尝试Array.prototype在编译时调用其成员,则不会出现类型错误,但它会在运行时失败.
更新的示例:
const script: HTMLScriptElement = document.getElementsByName(id).item(0) as HTMLScriptElement;
Run Code Online (Sandbox Code Playgroud)
说明文件:
| 归档时间: |
|
| 查看次数: |
152067 次 |
| 最近记录: |