简体   繁体   中英

.top missing from jquery TypeScript definition files?

I am using the following code:

$('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top });

Typescript is giving me an error message saying:

The property 'top' does not exist on value of type 'Object'

I am guessing something is missing from the jQuery definition file. Has anyone else seen this problem or is this something that's not normally used with jQuery? It's something I have not seen before.

For more information. Here is the code where this is used:

   $.fn.buildTableOfContent = function () {
        "use strict";
        var h2 = this.find('h2');
        if (h2.length > 0) {
            var h1 = this.find('h1:first');
            if (h1.length === 0) {
                h1 = this.prepend('<h1>Help</h1>').children(':first');
            }
            var menu = h1.wrap('<div class="h1 with-menu"></div>')
                    .after('<div class="menu"><img src="/Content/images/menu-open-arrow.png" width="16" height="16"><ul></ul></div>')
                    .next().children('ul');
            h2.each(function (i) {
                this.id = 'step' + i;
                menu.append('<li class="icon_down"><a href="#step' + i + '">' + $(this).html() + '</a></li>');
            });
            menu.find('a').click(function (event) {
                event.preventDefault();
                $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top });
            });
        }
        return this;
    };

From the jquery.d.ts file (line 374 in my version):

interface JQuery {
   ...
   offset(): Object;
   offset(coordinates: any): JQuery;
   offset(func: (index: any, coords: any) => any): JQuery;
   ...
}

By invoking the function with no parameters the type definition expects the function to return an Object type. I looked at the documentation for jQuery and you are correct, the returned object is expected to have top and left properties on it.

Unfortunately, since there's no such thing as overloading based on return type, you wont be able to add on another member onto the JQuery interface. Since, in this particular case, the type definition is simply not as specific as it should be I would recommend simply modifying your jquery.d.ts file and changing the return type so it looks as follows (perhaps string instead of number?):

offset(): { top : number; left : number; };

If you would rather not modify this file, you also have the option of casting the result to any before accessing any properties on it, example:

$('html, body').animate({ scrollTop: (<any> $($(this).attr('href')).offset()).top });

The downside is the cast will be necessary each time you invoke that function with no parameters.

instead of this

 $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top });

try this

 $('html, body').animate({ scrollTop: $(this).offset().top });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM