Tapescript: casting HTMLElement

quelqu'un sait jouer à la typographie?

je suis en train de le faire:

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

mais il me donne une erreur:

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

Je ne peux pas accéder au membre 'type' de l'élément script à moins de le lancer au bon type, mais je ne sais pas comment faire. j'ai cherché dans les docs & samples, mais je n'ai rien trouvé.

152
demandé sur Spongman 2012-10-02 12:33:05

12 réponses

dactylographié utilise '<>' pour entourer des moulages, de sorte que ce qui précède devient:

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

malheureusement, vous ne pouvez pas faire:

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

vous obtenez l'erreur

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

mais vous pouvez faire:

(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
213
répondu Spongman 2012-11-18 12:42:38

à partir de la version dactylographiée 0.9 le fichier lib.d.ts utilise des signatures de surcharge spécialisées qui renvoient les bons types d'appels à getElementsByTagName .

cela signifie que vous n'avez plus besoin d'utiliser les assertions de type pour changer le type:

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
33
répondu user75525 2014-01-15 23:48:40

vous pouvez toujours hacker le système de type en utilisant:

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
18
répondu Jack128 2012-10-02 19:22:27

À la fin:

  • réelle Array objet (pas un NodeList habillé comme un Array )
  • une liste qui est garantie pour inclure seulement HTMLElements , pas Node s force-moulé à HTMLElement s
  • une ambiance chaleureuse et douillette de faire La bonne Chose

Essayez ce qui suit:

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

de Profiter de.

11
répondu Johannes Fahrenkrug 2015-09-25 17:37:46

Juste pour clarifier, c'est correct.

ne peut pas convertir "NodeList" en "HTMLScriptElement []

comme NodeList n'est pas un tableau réel (par exemple, il ne contient pas .forEach , .slice , .push , etc...).

ainsi si elle convertissait en HTMLScriptElement[] dans le système de type, vous n'obtiendriez pas d'erreurs de type si vous essayiez d'appeler des membres Array.prototype sur elle au moment de la compilation, mais il serait l'échec au moment de l'exécution.

8
répondu Bill Ticehurst 2017-01-05 08:18:18

ne pas taper cast. Jamais. Utiliser le type de garde:

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.

Laisser le compilateur faire le travail pour vous et obtenez des erreurs lors de vos hypothèses trompez.

cela peut sembler exagéré dans ce cas, mais cela vous aidera beaucoup si vous revenez plus tard et changez le sélecteur, comme ajouter une classe qui manque dans le dom, par exemple.

8
répondu Benoit B. 2017-04-25 09:53:22

cela semble résoudre le problème, en utilisant le type d'accès [index: TYPE] tableau, santé.

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

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
3
répondu Tobiasz Cudnik 2012-10-05 08:37:09

pourrait être résolu dans le dossier de déclaration (lib.D. ts) si TypeScript définirait HTMLCollection au lieu de NodeList comme un type de retour.

DOM4 spécifie également que C'est le bon type de retour, mais les anciennes spécifications DOM sont moins claires.

Voir aussi http://typescript.codeplex.com/workitem/252

1
répondu Peter 2012-11-08 20:32:58

Puisqu'il s'agit d'un NodeList , pas d'un Array , vous ne devriez pas vraiment utiliser de crochets ou de casting à Array . La façon de propriété pour obtenir le premier noeud est:

document.getElementsByName(id).item(0)

vous pouvez juste lancer que:

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

Ou, étendre NodeList :

interface HTMLScriptElementNodeList extends NodeList
{
    item(index: number): HTMLScriptElement;
}
var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
    script = scripts.item(0);
0
répondu Mike Keesey 2013-12-19 17:09:31

je recommande également les guides de sitepen

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript (voir ci-dessous) et https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types /

dactylographié vous permet également de spécifier différents types de retour quand un exact chaîne est fournie comme argument d'une fonction. Exemple, Déclaration d'ambient de TypeScript pour la méthode createElement de DOM on dirait:

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

cela signifie, à la typographie, lorsque vous appelez par exemple document.createElement ('video'), Tapescript sait que la valeur de retour est un HTMLVideoElement et sera en mesure de s'assurer que vous êtes en interaction correctement avec L'API vidéo DOM sans besoin de taper assert.

0
répondu sebilasse 2015-08-25 18:35:18
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
0
répondu Radwan Ayoub 2018-09-02 13:36:56

exemple mis à jour:

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

de la Documentation:

Tapuscrit - Types de Base de Type affirmations

0
répondu Leo 2018-09-25 09:58:43