سؤال

هل يعرف أحد كيفية الإرسال في TypeScript؟

أحاول أن أفعل هذا:

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

لكنه يعطيني خطأ:

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

لا يمكنني الوصول إلى عضو "النوع" في عنصر البرنامج النصي إلا إذا قمت بإحالته إلى النوع الصحيح، لكنني لا أعرف كيفية القيام بذلك.لقد بحثت في المستندات والعينات، لكن لم أتمكن من العثور على أي شيء.

هل كانت مفيدة؟

المحلول

يستخدم Duxcript '<>' لإلقاء العروض المحيطية، لذلك يصبح ما سبق: giveacodicetagpre.

ومع ذلك، لسوء الحظ لا يمكنك القيام به: giveacodicetagpre.

تحصل على الخطأ giveacodicetagpre.

ولكن يمكنك القيام به: giveacodicetagpre.

نصائح أخرى

اعتبارًا من TypeScript 0.9 lib.d.ts يستخدم الملف توقيعات التحميل الزائد المتخصصة التي تُرجع الأنواع الصحيحة للمكالمات إليها getElementsByTagName.

هذا يعني أنك لم تعد بحاجة إلى استخدام تأكيدات النوع لتغيير النوع:

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

يمكنك دائما نظام الاختراق نوع باستخدام: giveacodicetagpre.

لا تكتب cast.مطلقا.استخدام الحراس النوع: giveacodicetagpre.

دع المحول البرمجي يقوم بالعمل من أجلك والحصول على أخطاء عندما تتحول افتراضاتك خطأ.

قد تبدو مبالغة في هذه الحالة، لكن ستساعدك كثيرا إذا عدت لاحقا وتغيير المحدد، مثل إضافة فئة مفقودة في DOM، على سبيل المثال.

To end up with:

  • an actual Array object (not a NodeList dressed up as an Array)
  • a list that is guaranteed to only include HTMLElements, not Nodes force-casted to HTMLElements
  • a warm fuzzy feeling to do The Right Thing

Try this:

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

Enjoy.

Just to clarify, this is correct.

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

as a NodeList is not an actual array (e.g. it doesn't contain .forEach, .slice, .push, etc...).

Thus if it did convert to HTMLScriptElement[] in the type system, you'd get no type errors if you tried to call Array.prototype members on it at compile time, but it would fail at run time.

Updated example:

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

Documentation:

TypeScript - Basic Types - Type assertions

This seems to solve the problem, using the [index: TYPE] array access type, cheers.

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

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

Could be solved in the declaration file (lib.d.ts) if TypeScript would define HTMLCollection instead of NodeList as a return type.

DOM4 also specifies this as the correct return type, but older DOM specifications are less clear.

See also http://typescript.codeplex.com/workitem/252

Since it's a NodeList, not an Array, you shouldn't really be using brackets or casting to Array. The property way to get the first node is:

document.getElementsByName(id).item(0)

You can just cast that:

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

Or, extend NodeList:

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

I would also recommend the sitepen guides

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (see below) and https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types/

TypeScript also allows you to specify different return types when an exact string is provided as an argument to a function. For example, TypeScript’s ambient declaration for the DOM’s createElement method looks like this:

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

This means, in TypeScript, when you call e.g. document.createElement('video'), TypeScript knows the return value is an HTMLVideoElement and will be able to ensure you are interacting correctly with the DOM Video API without any need to type assert.

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top