Dattiloscritto: fusione HTMLElement

voti
143

qualcuno sa come lanciare a macchina?

Sto cercando di fare questo:

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

ma mi sta dando un errore:

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

Non posso accedere al membro 'tipo' dell'elemento script a meno ho gettato al tipo corretto, ma non so come fare. ho cercato la documentazione e campioni, ma non ho trovato nulla.

È pubblicato 02/10/2012 alle 09:33
fonte dall'utente
In altre lingue...                            


12 risposte

voti
202

Dattiloscritto usa '<>' circondare calchi, in modo che il diventa di cui sopra:

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

Tuttavia, purtroppo, non si può fare:

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

Si ottiene l'errore

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

Ma si può fare:

(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Risposto il 02/10/2012 a 09:47
fonte dall'utente

voti
33

A partire dal dattiloscritto 0,9 del lib.d.tsfile utilizza le firme di sovraccarico specializzati che restituiscono i tipi corretti per le chiamate verso getElementsByTagName.

Questo significa che non è più necessario utilizzare tipo asserzioni per cambiare il tipo:

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
Risposto il 16/01/2014 a 00:48
fonte dall'utente

voti
17

È sempre possibile hackerare tipo di sistema utilizzando:

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Risposto il 02/10/2012 a 20:22
fonte dall'utente

voti
12

Per finire con:

  • un effettivo Arrayoggetto (non un NodeListvestito come unArray )
  • un elenco che è garantito per includere solo HTMLElements, non Nodes forza-casted aHTMLElement s
  • una sensazione inebriante di fare la cosa giusta

Prova questo:

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

Godere.

Risposto il 25/09/2015 a 17:37
fonte dall'utente

voti
9

Giusto per chiarire, questo è corretto.

Impossibile convertire 'NodeList' a 'HTMLScriptElement []'

come NodeListnon è una matrice reale (ad esempio esso non contiene .forEach, .slice, .push, ecc ...).

Così, se lo ha fatto convertire HTMLScriptElement[]nel sistema tipo, si otterrebbe nessun errore di tipo se si è tentato di chiamare Array.prototypei membri su di esso al momento della compilazione, ma sarebbe fallire in fase di esecuzione.

Risposto il 02/10/2012 a 20:19
fonte dall'utente

voti
8

Non digitare cast. Mai. Utilizzare tipo guardie:

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.

Lasciate che il compilatore fare il lavoro per voi e ottenere gli errori quando le tue supposizioni si rivelano sbagliate.

Può sembrare eccessivo, in questo caso, ma vi aiuterà molto se si torna tardi e cambiare il selettore, come l'aggiunta di una classe che manca nel DOM, per esempio.

Risposto il 20/04/2017 a 17:18
fonte dall'utente

voti
4

Questo sembra risolvere il problema, utilizzando il [index: TYPE]tipo di accesso matrice, salute.

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

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
Risposto il 05/10/2012 a 09:37
fonte dall'utente

voti
2

Esempio Aggiornato:

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

Documentazione:

Dattiloscritto - tipi di base - Tipo asserzioni

Risposto il 25/09/2018 a 09:58
fonte dall'utente

voti
2

Potrebbe essere risolto nel file di dichiarazione (lib.d.ts) se dattiloscritto definirebbe HTMLCollection invece di NodeList come un tipo di ritorno.

DOM4 specifica anche questo come il tipo di ritorno corretto, ma le specifiche DOM più anziani sono meno chiare.

Vedi anche http://typescript.codeplex.com/workitem/252

Risposto il 08/11/2012 a 21:32
fonte dall'utente

voti
1

Suggerirei anche le guide SitePen

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (vedi sotto) e https://www.sitepen.com/blog/2014/08/22/advanced -typescript-Concepts-classi-types /

Dattiloscritto permette inoltre di specificare i diversi tipi di ritorno quando una stringa esatta viene fornito come argomento a una funzione. Ad esempio, la dichiarazione ambientale di tipografico per il metodo createElement del DOM è simile al seguente:

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

Questo significa che, a macchina, quando si chiama ad esempio document.createElement ( 'video'), dattiloscritto conosce il valore di ritorno è un HTMLVideoElement e sarà in grado di assicurare si interagisce correttamente con le API DOM video senza la necessità di digitare assert.

Risposto il 25/08/2015 a 18:35
fonte dall'utente

voti
1

Dal momento che è una NodeList, non una Array, non si dovrebbe essere molto usare staffe o la fusione a Array. Il modo proprietà per ottenere il primo nodo è:

document.getElementsByName(id).item(0)

Si può solo lanciare quella:

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

Oppure, si estendono NodeList:

interface HTMLScriptElementNodeList extends NodeList
{
    item(index: number): HTMLScriptElement;
}
var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
    script = scripts.item(0);
Risposto il 19/12/2013 a 18:09
fonte dall'utente

voti
0
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
Risposto il 02/09/2018 a 13:36
fonte dall'utente

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