Машинопись: литье HTMLElement

голоса
143

Кто-нибудь знает, как бросить в машинописном?

Я пытаюсь сделать это:

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

Я не могу получить доступ к элементу «типа» элемента сценария, если я не отбрасываю его к правильному типу, но я не знаю, как это сделать. Я искал документацию & образцы, но я не мог найти что-нибудь.

Задан 02/10/2012 в 09:33
источник пользователем
На других языках...                            


12 ответов

голоса
202

Машинопись использует «<>», чтобы окружить слепки, поэтому выше становится:

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];
Ответил 02/10/2012 в 09:47
источник пользователем

голоса
33

По состоянию на машинописи 0.9 lib.d.tsфайл использует специализированные подписи перегрузки , которые возвращают правильные типы для звонков getElementsByTagName.

Это означает, что вам больше не нужно использовать утверждение типа для изменения типа:

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
Ответил 16/01/2014 в 00:48
источник пользователем

голоса
17

Вы всегда можете взломать систему типа с помощью:

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Ответил 02/10/2012 в 20:22
источник пользователем

голоса
12

Для того, чтобы в конечном итоге с:

  • фактический Arrayобъект (не NodeListодет как Array)
  • список , который гарантированно включать только HTMLElements, а не Nodeс силой, отлиты в HTMLElementсек
  • теплое нечеткое чувство, чтобы сделать правильную вещь

Попробуй это:

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);
        }
    }
}

Наслаждаться.

Ответил 25/09/2015 в 17:37
источник пользователем

голоса
9

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

Невозможно преобразовать «NodeList» в 'HTMLScriptElement []

как NodeListэто не реальный массив (например , он не содержит .forEach, .slice, .pushи т.д. ...).

Таким образом , если бы это было преобразовать HTMLScriptElement[]в системе типов, вы не получили бы никаких ошибок типа , если вы пытались дозвониться Array.prototypeпользователями на нем во время компиляции, но она потерпит неудачу во время выполнения.

Ответил 02/10/2012 в 20:19
источник пользователем

голоса
8

Не вводите актер. Никогда. Используйте защитные типа:

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.

Пусть компилятор делать работу за вас и получить ошибки, когда ваши предположения оказываются неправильно.

Это может выглядеть излишество в этом случае, но это поможет вам много, если вы вернетесь позже и изменить селектор, как добавить класс, который отсутствует в йоте, например.

Ответил 20/04/2017 в 17:18
источник пользователем

голоса
4

Это , кажется , решить эту проблему, используя [index: TYPE]тип доступа к массиву, приветствия.

interface ScriptNodeList extends NodeList {
    [index: number]: HTMLScriptElement;
}

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
Ответил 05/10/2012 в 09:37
источник пользователем

голоса
2

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

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

Документация:

Машинопись - Основные виды - тип утверждения

Ответил 25/09/2018 в 09:58
источник пользователем

голоса
2

Может быть решены в файл декларации (lib.d.ts), если машинопись будет определять HTMLCollection вместо NodeList в качестве типа возвращаемого значения.

DOM4 также определяет это как правильный тип возвращаемого значения, но более старые спецификации DOM менее ясны.

Смотрите также http://typescript.codeplex.com/workitem/252

Ответил 08/11/2012 в 21:32
источник пользователем

голоса
1

Я хотел бы также рекомендовать sitepen направляющие

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (смотри ниже) и https://www.sitepen.com/blog/2014/08/22/advanced -typescript-концепции-классы-типов /

Машинопись также позволяет определить различные типы возврата, когда точная строка приводится в качестве аргумента функции. Например, эмбиент декларация Машинопись для метода createElement в DOM выглядит следующим образом:

createElement(tagName: 'a'): HTMLAnchorElement;
createElement(tagName: 'abbr'): HTMLElement;
createElement(tagName: 'address'): HTMLElement;
createElement(tagName: 'area'): HTMLAreaElement;
// ... etc.
createElement(tagName: string): HTMLElement;

Это означает, что в машинописном, когда вы звоните, например document.createElement ( «видео»), машинопись знает возвращаемое значение является HTMLVideoElement и будет иметь возможность убедиться, что вы правильно взаимодействовать с DOM Video API без необходимости вводить Assert.

Ответил 25/08/2015 в 18:35
источник пользователем

голоса
1

Так как это 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);
Ответил 19/12/2013 в 18:09
источник пользователем

голоса
0
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
Ответил 02/09/2018 в 13:36
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more