type ts2339 tipo propiedad property not htmlinputelement htmlelement existe exist error does typescript

ts2339 - TypeScript: casting HTMLElement



property value does not exist on type htmlelement (10)

Alguien sabe cómo lanzar en TypeScript?

Estoy tratando de hacer esto:

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

pero me está dando un error:

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

No puedo acceder al elemento ''tipo'' del elemento script a menos que lo lance al tipo correcto, pero no sé cómo hacerlo. busqué en los documentos y las muestras, pero no pude encontrar nada.


A partir de TypeScript 0.9, el archivo lib.d.ts utiliza firmas de sobrecarga especializadas que devuelven los tipos correctos para las llamadas a getElementsByTagName .

Esto significa que ya no necesita usar aserciones de tipo para cambiar el tipo:

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


Como es una NodeList , no una Array , realmente no deberías estar usando corchetes o casting en Array . La forma de propiedad para obtener el primer nodo es:

document.getElementsByName(id).item(0)

Puedes simplemente lanzar eso:

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

O extienda NodeList :

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


Esto parece resolver el problema, usando el tipo de acceso de matriz [index: TYPE] , cheers.

interface ScriptNodeList extends NodeList { [index: number]: HTMLScriptElement; } var script = ( <ScriptNodeList>document.getElementsByName(''foo'') )[0];


No escribir elenco Nunca. Use guardias de tipo:

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.

Deje que el compilador haga el trabajo por usted y obtenga errores cuando sus suposiciones resulten incorrectas.

Puede parecer excesivo en este caso, pero te ayudará mucho si vuelves más tarde y cambias el selector, como agregar una clase que falta en el dom, por ejemplo.


Para terminar con:

  • un objeto Array real (no una NodeList disfrazada como una Array )
  • una lista que garantiza que solo incluye HTMLElements , no Node s HTMLElement -casted a HTMLElement s
  • una sensación cálida y difusa de hacer lo correcto

Prueba esto:

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

Disfrutar.


Podría resolverse en el archivo de declaración (lib.d.ts) si TypeScript definiera HTMLCollection en lugar de NodeList como un tipo de devolución.

DOM4 también especifica esto como el tipo de devolución correcto, pero las especificaciones DOM más antiguas son menos claras.

Ver también http://typescript.codeplex.com/workitem/252


Siempre puedes hackear el sistema de tipos usando:

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


Solo para aclarar, esto es correcto.

No se puede convertir ''NodeList'' a ''HTMLScriptElement []''

como NodeList no es una matriz real (por ejemplo, no contiene .forEach , .slice , .push , etc.).

Por lo tanto, si se convirtiera en HTMLScriptElement[] en el sistema de tipos, no obtendría ningún tipo de error si intentara llamar miembros de Array.prototype en el momento de la compilación, pero fallaría en tiempo de ejecución.


También recomendaría las guías de sitio

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (ver a continuación) y https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types/

TypeScript también le permite especificar diferentes tipos de devolución cuando se proporciona una cadena exacta como argumento para una función. Por ejemplo, la declaración ambiental de TypeScript para el método createElement de DOM tiene este aspecto:

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

Esto significa que, en TypeScript, cuando llame, por ejemplo, document.createElement (''video''), TypeScript sabe que el valor devuelto es un HTMLVideoElement y podrá garantizar que está interactuando correctamente con DOM Video API sin necesidad de escribir assert.


TypeScript usa ''<>'' para rodear moldes, por lo que lo anterior se convierte en:

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

Sin embargo, lamentablemente no puedes hacer:

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

Obtienes el error

Cannot convert ''NodeList'' to ''HTMLScriptElement[]''

Pero puedes hacer:

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