23

I'm rewriting some JS code on TypeScript and encounter with problems with module import. For example, I want to write my toggleVisiblity function. Here is code:

/// <reference path="../../typings/jquery/jquery.d.ts" />

import * as $ from "jquery";

interface JQuery {
    toggleVisibility(): JQuery;
}

$.fn.extend({
    toggleVisibility: function () {
        return this.each(function () {
            const $this = $(this);
            const visibility = $this.css('visibility') === 'hidden' ? 'visible' : 'hidden';
            $this.css('visibility', visibility);
        });
    }
});

const jQuery = $('foo');
const value = jQuery.val();
jQuery.toggleVisibility();

But the problem is that for unknown reason toggleVisibility is not added to JQuery interface thus I get an error Property 'toggleVisibility' does not exist on type 'JQuery'., although it sees other methods (val, each and so on).

Why is it not working?

enter image description here

1
  • It seems your interface JQuery is not merged with the original one. Maybe it should be imported. How have you imported the definitions for jQuery ? With the new @types system? Commented Dec 3, 2016 at 17:26

3 Answers 3

39

Try putting the

interface JQuery {
    toggleVisibility(): JQuery;
}

Inside a seperate file without import/export statements. This works for me. Though it wold be interesting to know why.

EDIT: There is an excellent explanation for this behaviour in this answer to post: How to extend the 'Window' typescript interface

Sign up to request clarification or add additional context in comments.

4 Comments

I'm going to create an issue in TS github, maybe it will be fixed. Thank you for an answer.
@AlexZhukovskiy Please give the link to the issue, I'm interested too.
For those who are struggling to know where to put this file (like myself); this link explains very well.
Oh thank goodness I found this post. I was starting to grow gray hairs over documenting this API.
11

I got the solution, this worked for me:

Use the JQueryStatic interface for static jQuery access like $.jGrowl(...) or jQuery.jGrowl(...) or in your case, jQuery.toggleVisibility():

interface JQueryStatic {

    ajaxSettings: any;

    jGrowl(object?, f?): JQuery;

}

And for your own custom made functions you use using jQuery.fn.extend, use the JQuery interface:

interface JQuery {

    fileinput(object?): void;//custom jquery plugin, had no typings

    enable(): JQuery;

    disable(): JQuery;

    check(): JQuery;

    select_custom(): JQuery;

}

Optional, here are my extended JQuery functions:

jQuery.fn.extend({
    disable: function () {
        return this.each(function () {
            this.disabled = true;
        });
    },
    enable: function () {
        return this.each(function () {
            this.disabled = false;
        });
    },
    check: function (checked) {
        if (checked) {
            $(this).parent().addClass('checked');
        } else {
            $(this).parent().removeClass('checked');
        }
        return this.prop('checked', checked);
    },
    select_custom: function (value) {
        $(this).find('.dropdown-menu li').each(function () {
            if ($(this).attr('value') == value) {
                $(this).click();
                return;
            }
        });
    }
});

1 Comment

This approach seems to clobber the JQuery declarations for regular functions, like .click() and .parent(). Any idea why?
0

I had a similar problem but with my bootstrapDP function extending JQuery in the same way.

Solution:

    declare global {
        interface JQuery {
            bootstrapDP: any;  // replace 'any' with the actual type if known
        }
    }

Explanation:

This code declares a global augmentation of the JQuery interface, adding my bootstrapDP method to it. After adding this code, TypeScript should recognize bootstrapDP as a method on jQuery objects.

Here is some documentation about global auhmentation: link

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.