Tuesday, September 5, 2017

Back to the roots: defining a jQuery plugin in TypeScript

The problem

You're so proficient in TypeScript that you decided all your code will be type-safe. All that is left is this damn jQuery plugin that won't bow to your will and you have no idea how to make all the typing information work.

The solution

This is actually quite easy! Let's start with the obvious import:

    import * as $ from 'jquery'

Next you need to decide if your plugin will take configuration options. If that is the case then you need an interface describing those options

    interface FooOptions {
      color?: string
    }

Now we need to tell TypeScript that we're going to extend the global JQuery interface with our method:

    declare global {
      interface JQuery {
        foo(options?: FooOptions): JQuery
      }
    }

The question mark after options means this is an optional parameter and if not defined then an undefined value will be passed on

All that is left is to write the plugin itself

    $.fn.foo = function(this: JQuery, options?: FooOptions) {
      const settings: FooOptions = {
        color: 'blue',
        ...options,
      }
      return this.each(function() {
        $(this).css({ 'background-color': settings.color })
      })
    }

The method signature tells TypeScript that this in this context is a jQuery object and that there can be a FooOptions passed on.

The rest is obvious: using object spread operator we get the actual set of settings and next we just go on with the plugin's body.

Happy coding!

No comments: