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, если я не приведу его к правильному типу, но я не знаю, как это сделать. я искал документы и образцы, но я ничего не мог найти.

535   12  

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 объект (не a NodeList одеты как Array)
  • список, который гарантированно содержать только HTMLElements, а не NodeS force-casted to 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);
        }
    }
}

наслаждайтесь.

просто чтобы уточнить, это правильно.

не удается преобразовать '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.

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    

обновлен пример:

const script: HTMLScriptElement = document.getElementsByName(id).item(0) as HTMLScriptElement;

документы:

TypeScript-основные типы-утверждения типа

Comments

    Ничего не найдено.