TypeScript: döküm HTMLElement


198

TypeScript'te nasıl yayın yapılacağını bilen var mı?

Bunu yapmaya çalışıyorum:

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

ama bana bir hata veriyor:

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

Ben doğru türe döküm sürece script öğesinin 'type' üyesi erişemiyorum, ama bunu nasıl yapacağımı bilmiyorum. Dokümanları ve örnekleri aradım, ancak hiçbir şey bulamadım.


Bu döküm sorununun artık 0.9'da mevcut olmadığını unutmayın.
Greg Gum

@GregGum Bir Steve tarafından cevap
görmüyorum

Yanıtlar:


255

TypeScript, çevrimleri çevrelemek için '<>' kullanır, böylece aşağıdakiler olur:

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

Ancak, ne yazık ki yapamazsınız:

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

Hatayı alıyorsun

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

Ancak şunları yapabilirsiniz:

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

Bu daha fazla bakmak gerektiğini düşünüyorum, $ ('[type: input]') kullanın. / get, döküm kullanımı (<HTMLSelectElement> <any> element) .selectedIndex = 0; elemanın etrafına () ekler, çirkin
rekna


Uzun vadede (0.9 çıktıktan sonra), NodeList <HtmlScriptElement> gibi bir şeye yayınlayabilmelisiniz, ayrıca getElementsByName, herhangi bir döküm yapmadan bu hakkı elde etmek için dize değişmez tip geçersiz kılmaları kullanabilecektir!
Peter Burns

3
1.0'dan sonra sözdizimi olmalıdır(<NodeListOf<HTMLScriptElement>>document.getElementsByName(id))[0];
Will Huang

1
Döküm olarak da kullanabilirsiniz. HTMLScriptElement olarak var script = document.getElementsByName ("script") [0];
JGFMK

36

TypeScript 0.9'dan itibaren lib.d.tsdosya, çağrılar için doğru türleri döndüren özel aşırı yük imzaları kullanır getElementsByTagName.

Bu, türü değiştirmek için artık tür önerilerini kullanmanız gerekmediği anlamına gelir:

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

nesne gösteriminde nasıl yapıyorsunuz? yani yapamam {name: <HTMLInputElement>: document.querySelector ('# app-form [name]'). değer,}
Nikos

3
bu işe yaradı: name: (<HTMLInputElement> document.querySelector ('# app-form [name]')). değer,
Nikos

22

Döküm yazmayın. Asla. Tip korumaları kullanın:

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.

Bırakın, derleyicinin işi sizin için yapmasına izin verin ve varsayımlarınız yanlış olduğunda hatalar alın.

Bu durumda aşırıya kaçabilir gibi görünebilir, ancak daha sonra geri dönüp seçiciyi değiştirirseniz, örneğin dom'da eksik bir sınıf eklemek gibi, size çok yardımcı olacaktır.


21

Her zaman aşağıdakileri kullanarak tip sistemini hackleyebilirsiniz:

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

<any> kullanmak, geliştirme sırasında ideal değil, serin bir tip kontrolüne izin verir
tit

13

Son olarak:

  • gerçek bir Arraynesne ( NodeListgiyinmiş değil gibi Array)
  • dahil ancak garanti edecek bir liste HTMLElementsdeğildir, Nodes kuvvet döküm HTMLElements
  • doğru şey yapmak için sıcak bir bulanık duygu

Bunu dene:

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

Zevk almak.


10

Değişkenimizi açık bir dönüş türüyle yazabiliriz :

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

Ya assert olarak (ile gerekli TSX ):

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

Veya daha basit durumlarda, köşeli parantez sözdizimi ile onaylayın.


Bir tür iddiası diğer dillerde dökülen bir tür gibidir, ancak verilerin özel bir kontrolünü veya yeniden yapılandırılmasını gerçekleştirmez. Çalışma zamanı etkisi yoktur ve yalnızca derleyici tarafından kullanılır.

Belgeler:

TypeScript - Temel Türler - Tür iddiaları


9

Sadece açıklığa kavuşturmak için, bu doğrudur.

'NodeList', 'HTMLScriptElement []' biçimine dönüştürülemiyor

Bir şekilde NodeListgerçek bir dizi değil (o içermiyor örneğin .forEach, .slice, .push, vs ...).

Böylece HTMLScriptElement[]tür sistemine dönüştürdüyse Array.prototype, derleme zamanında üyelerini çağırmayı denerseniz tür hataları almazsınız , ancak çalışma zamanında başarısız olur.


1
bu doğru, ancak tamamen yararlı değildir. alternatif, herhangi bir yararlı tip kontrolü sağlamayan 'herhangi' üzerinden
geçmektir

3

Bu, [index: TYPE]dizi erişim türünü kullanarak sorunu çözüyor gibi görünüyor .

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

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

1

TypeScript, dönüş türü olarak NodeList yerine HTMLCollection tanımlayacaksa bildirim dosyasında (lib.d.ts) çözülebilir.

DOM4 de bunu doğru dönüş türü olarak belirtir, ancak eski DOM spesifikasyonları daha az nettir.

Ayrıca bkz http://typescript.codeplex.com/workitem/252


0

Bir NodeListdeğil, çünkü Array, gerçekten parantez veya döküm kullanmamalısınız Array. İlk düğümü almanın özellik yolu:

document.getElementsByName(id).item(0)

Sadece bunu yapabilirsiniz:

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

Veya, uzatın NodeList:

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

1
GÜNCELLEME Döküm şimdi şöyle görünüyor:const script = document.getElementsByName(id).item(0) as HTMLScriptElement;
Mike Keesey

Yani, TS 2.3 için "böyle görünüyor".
markeissler

0

Ayrıca sitepen kılavuzlarını tavsiye ederim

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (aşağıya bakın) ve https://www.sitepen.com/blog/2014/08/22/advanced -typescript-kavramlar sınıfları-türleri /

TypeScript ayrıca bir işleve bağımsız değişken olarak tam bir dize sağlandığında farklı dönüş türleri belirtmenize olanak tanır. Örneğin, TypeScript'in DOM'un createElement yöntemi için ortam bildirimi şöyle görünür:

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

Bu, TypeScript'te, örneğin document.createElement ('video') öğesini çağırdığınızda, TypeScript, dönüş değerinin bir HTMLVideoElement olduğunu bilir ve herhangi bir onay yazmaya gerek kalmadan DOM Video API ile doğru bir şekilde etkileşimde bulunabilmenizi sağlar.


0
var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.