Pergunta

Alguém sabe como lançar no TypeScript?

Eu estou tentando fazer isso:

var script:HTMLScriptElement = document.getElementsByName("script")[0];
alert(script.type);

mas ele está me dando um erro:

Cannot convert 'Node' to 'HTMLScriptElement': Type 'Node' is missing property 'defer' from type 'HTMLScriptElement'
(elementName: string) => NodeList

Eu não posso acessar o 'tipo' de membro do elemento de script, a menos que eu o lancei para o tipo correto, mas eu não sei como fazer isso.Eu procurei o docs & samples, mas eu não consegui encontrar nada.

Foi útil?

Solução

Transcrito usa '<>' para surround lança, de modo que o acima torna-se:

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

No entanto, infelizmente, você não pode fazer:

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

Você obter o erro

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

Mas você pode fazer :

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

Outras dicas

Como o TypeScript de 0,9 a lib.d.ts usa de arquivo especializado sobrecarga de assinaturas que retornam os tipos corretos para chamadas de getElementsByTagName.

Isso significa que você não precisa usar o tipo de afirmações para alterar o tipo:

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);

Você sempre pode cortar tipo de sistema utilizando:

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

Não escreva elenco.Nunca.Tipo de uso de guardas:

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.

Deixar que o compilador faça o trabalho para você e obter erros quando seus pressupostos a dar errado.

Pode parecer um exagero nesse caso, mas ele vai ajudar muito se você voltar e mudar o seletor, como a adição de uma classe que está em falta no dom, por exemplo.

Para acabar com:

  • um real Array objeto (e não um NodeList vestido como um Array)
  • uma lista que é garantido para incluir apenas HTMLElements, não Nodes força-casted a HTMLElements
  • uma estranha sensação quente por fazer A Coisa Certa

Tente isso:

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

Desfrute.

Só para esclarecer, isso é correto.

Não é possível converter 'NodeList" para " HTMLScriptElement[]'

como um NodeList não é uma matriz real (e.g.ele não contém .forEach, .slice, .push, etc...).

Assim se converteram ao HTMLScriptElement[] no tipo de sistema, você pegaria nenhum tipo de erros se você tentar ligar para Array.prototype membros sobre ele em tempo de compilação, mas ele poderia falhar em tempo de execução.

Atualizado exemplo:

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

Documentação:

O TypeScript - Tipos Básicos - Tipo de afirmações

Isso parece resolver o problema, usando o [index: TYPE] matriz de tipo de acesso, felicidades.

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

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];

Poderiam ser resolvidos no arquivo de declaração (lib.d.ts) se Transcrito definiria HTMLCollection em vez de NodeList como um tipo de retorno.

DOM4 também especifica este como o tipo de retorno, mas mais de DOM especificações são menos claros.

Veja também http://typescript.codeplex.com/workitem/252

Já que é um NodeList, não Array, você realmente não deve ser a utilizar parênteses ou de fundição para Array.A propriedade de forma a obter o primeiro nó é:

document.getElementsByName(id).item(0)

Você pode apenas lançar-se de que:

var script = <HTMLScriptElement> document.getElementsByName(id).item(0)

Ou, estender NodeList:

interface HTMLScriptElementNodeList extends NodeList
{
    item(index: number): HTMLScriptElement;
}
var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
    script = scripts.item(0);

Eu também recomendaria o sitepen guias

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (veja abaixo) e https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types/

TypeScript também lhe permite especificar diferentes tipos de retorno, quando um seqüência exata é fornecido como um argumento para uma função.Por exemplo, Transcrito do ambiente declaração para o DOM do método createElement este aspecto:

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

Isso significa que, na Transcrição, quando você chamar e.g.documento.createElement('video'), Transcrito sabe o valor de retorno é um HTMLVideoElement e será capaz de assegurar que você está interagindo corretamente com o DOM de Vídeo API, sem qualquer necessidade de fazer um tipo de declaração.

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top