TypeScript: литье HTMLElement
кто-нибудь знает, как бросить в TypeScript?
Я пытаюсь сделать это:
var script:HTMLScriptElement = document.getElementsByName("script")[0];
alert(script.type);
но это дает мне ошибку:
Cannot convert 'Node' to 'HTMLScriptElement': Type 'Node' is missing property 'defer' from type 'HTMLScriptElement'
(elementName: string) => NodeList
Я не могу получить доступ к элементу 'type' элемента script, если я не приведу его к правильному типу, но я не знаю, как это сделать. я искал документы и образцы, но я ничего не мог найти.
12 ответов:
TypeScript использует ' ' для окружения слепков, поэтому выше становится:
var script = <HTMLScriptElement>document.getElementsByName("script")[0];однако, к сожалению, вы не можете сделать:
var script = (<HTMLScriptElement[]>document.getElementsByName(id))[0];вы получили ошибку
Cannot convert 'NodeList' to 'HTMLScriptElement[]'но вы можете сделать :
(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
по состоянию на TypeScript 0.9 the
lib.d.tsфайл использует специализированные сигнатуры перегрузки, которые возвращают правильные типы для вызововgetElementsByTagName.Это означает, что вам больше не нужно использовать утверждения типа для изменения типа:
// No type assertions needed var script: HTMLScriptElement = document.getElementsByTagName('script')[0]; alert(script.type);
вы всегда можете взломать систему типа:
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
в итоге:
- фактический
Arrayобъект (не aNodeListодеты какArray)- список, который гарантированно содержать только
HTMLElements, а неNodeS force-casted toHTMLElements- теплое нечеткое чувство, чтобы сделать правильную вещь
попробуйте это:
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); } } }наслаждайтесь.
просто чтобы уточнить, это правильно.
не удается преобразовать 'NodeList' в ' HTMLScriptElement []'
как
NodeListне является фактическим массивом (например, он не содержит.forEach,.slice,.pushи т. д...).таким образом, если он преобразуется в
HTMLScriptElement[]в системе типов вы не получите ошибок типа, если попытаетесь вызватьArray.prototypeчлены на нем во время компиляции, но это приведет к сбою во время выполнения.
Не приведение типа. Никогда. Используйте тип охранников:
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.пусть компилятор сделает работу за вас и получит ошибки, когда ваши предположения окажутся неверными.
это может показаться излишним в этом случае, но это поможет вам много, если вы вернетесь позже и измените селектор, например, добавив класс, который отсутствует в dom, например.
это, кажется, решить проблему, используя
[index: TYPE]тип доступа к массиву, ура.interface ScriptNodeList extends NodeList { [index: number]: HTMLScriptElement; } var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
может быть решена в файле объявления (lib.d.ts) если TypeScript определит HTMLCollection вместо NodeList в качестве возвращаемого типа.
DOM4 также указывает это как правильный тип возврата, но более старые спецификации DOM менее ясны.
Смотрите также http://typescript.codeplex.com/workitem/252
С
NodeList, а неArray, вы не должны действительно использовать скобки или литье вArray. Свойство способ получить первый узел является:document.getElementsByName(id).item(0)вы можете просто бросить, что:
var script = <HTMLScriptElement> document.getElementsByName(id).item(0)или продлить
NodeList:interface HTMLScriptElementNodeList extends NodeList { item(index: number): HTMLScriptElement; } var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'), script = scripts.item(0);
Я бы также рекомендовал гиды sitepen
https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (см. ниже) и https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types/
TypeScript также позволяет указать различные типы возвращаемых данных, когда точную строку в качестве аргумента функции. Например, Эмбиент объявление машинопись на дом метод метод createElement выглядит так:
createElement(tagName: 'a'): HTMLAnchorElement; createElement(tagName: 'abbr'): HTMLElement; createElement(tagName: 'address'): HTMLElement; createElement(tagName: 'area'): HTMLAreaElement; // ... etc. createElement(tagName: string): HTMLElement;Это означает, в TypeScript, когда вы вызываете, например документ.createElement ('video'), TypeScript знает возвращаемое значение HTMLVideoElement и сможет гарантировать, что вы взаимодействуете правильно с DOM Video API без необходимости вводить assert.
обновлен пример:
const script: HTMLScriptElement = document.getElementsByName(id).item(0) as HTMLScriptElement;документы:
Comments