Typescript: casting Lijst van HTML-elementen

stemmen
143

iedereen weet hoe je gegoten in typoscript?

Ik probeer om dit te doen:

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

maar het geeft me een fout:

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

Ik kan geen toegang tot het 'type' lid van het script element tenzij ik wierp het om het juiste type, maar ik weet niet hoe dit te doen. Ik zocht de docs & monsters, maar ik kon niets vinden.

De vraag is gesteld op 02/10/2012 om 09:33
bron van user
In andere talen...                            


12 antwoorden

stemmen
202

Typoscript gebruikt '<>' om afgietsels te omringen, zodat de bovenstaande wordt:

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

Echter, helaas kun je niet doen:

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

U krijgt de fout

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

Maar je kunt doen:

(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
antwoordde op 02/10/2012 om 09:47
bron van user

stemmen
33

Met ingang van getypte 0,9 het lib.d.tsbestand gebruikt gespecialiseerde overbelasting handtekeningen die de juiste types terug voor oproepen naar getElementsByTagName.

Dit betekent dat je niet meer hoeft te soort beweringen te gebruiken om het type te veranderen:

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
antwoordde op 16/01/2014 om 00:48
bron van user

stemmen
17

U kunt altijd het type systeem te hacken met behulp van:

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
antwoordde op 02/10/2012 om 20:22
bron van user

stemmen
12

Om te eindigen met:

  • een actuele Arrayobject (niet NodeListgekleed als Array)
  • een lijst die is gegarandeerd om alleen HTMLElements, niet Nodes force-gegoten om HTMLElements
  • een warm fuzzy gevoel om het juiste te doen

Probeer dit:

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

Genieten.

antwoordde op 25/09/2015 om 17:37
bron van user

stemmen
9

Gewoon om te verduidelijken, dit juist is.

Kan 'nodelist' niet om te zetten in 'HTMLScriptElement []'

als NodeListgeen daadwerkelijke array (bijvoorbeeld het niet bevat .forEach, .slice, .push, etc ...).

Dus als het wel om te zetten HTMLScriptElement[]in het type-systeem, zou je geen typefouten als je probeerde te bellen Array.prototypeleden op het op het compileren, maar het zou mislukken tijdens runtime.

antwoordde op 02/10/2012 om 20:19
bron van user

stemmen
8

Typ niet cast. Nooit. Gebruik soort bewakers:

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.

Laat de compiler doen het werk voor u en krijg fouten wanneer je aannames blijken niet te kloppen.

Het kan overkill kijken in dit geval, maar het zal u veel helpen als je later terug te komen en verander de selector, zoals het toevoegen van een klasse die ontbreekt in de dom, bijvoorbeeld.

antwoordde op 20/04/2017 om 17:18
bron van user

stemmen
4

Dit lijkt om het probleem op te lossen, met behulp van de [index: TYPE]toegang arraytype, gejuich.

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

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
antwoordde op 05/10/2012 om 09:37
bron van user

stemmen
2

Bijgewerkt voorbeeld:

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

Documentatie:

Typescript - basistypen - Type beweringen

antwoordde op 25/09/2018 om 09:58
bron van user

stemmen
2

Zou kunnen worden opgelost in de verklaring file (lib.d.ts) als typoscript HTMLCollection plaats van nodelist zou definiëren als een terugkeer type.

DOM4 geeft dit ook de juiste terugkeertype, maar oudere DOM specificaties zijn minder duidelijk.

Zie ook http://typescript.codeplex.com/workitem/252

antwoordde op 08/11/2012 om 21:32
bron van user

stemmen
1

Ik zou ook de sitepen gidsen

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (zie hieronder) en https://www.sitepen.com/blog/2014/08/22/advanced -typescript-concepten-classes-types /

Typescript kunt u ook verschillende soorten terugkeer vermeld wanneer de exacte reeks wordt geleverd als een argument voor een functie. Bijvoorbeeld, typoscript van ambient-aangifte voor de DOM's createElement methode ziet er als volgt uit:

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

Dit betekent, in typoscript, wanneer u belt bijvoorbeeld document.createElement ( 'video'), typoscript kent de return waarde is een HTMLVideoElement en in staat om te zorgen dat u de juiste manier zijn interactie met de DOM Video API zonder enige noodzaak om te beweren typen zal zijn.

antwoordde op 25/08/2015 om 18:35
bron van user

stemmen
1

Aangezien het een NodeList, niet een Array, moet je niet echt worden met behulp van beugels of gieten aan Array. Het pand manier om het eerste knooppunt te krijgen is:

document.getElementsByName(id).item(0)

Je kunt gewoon gegoten dat:

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

Of, uit te breiden NodeList:

interface HTMLScriptElementNodeList extends NodeList
{
    item(index: number): HTMLScriptElement;
}
var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
    script = scripts.item(0);
antwoordde op 19/12/2013 om 18:09
bron van user

stemmen
0
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
antwoordde op 02/09/2018 om 13:36
bron van user

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