Coding a closure in TypeScript

MatthewScarpino picture MatthewScarpino · Sep 3, 2015 · Viewed 17.7k times · Source

Just for amusement, I'm trying to use TypeScript's strong typing in code containing a closure. Here's what the original JavaScript code looks like:

var func = (function() {

  var private_count = 0;

  var increment = function() {
    private_count += 1;
    return private_count;
  }

  return increment;
}());

Here's my best attempt to implement this with TypeScript:

var func: ()=>()=>number = (function(): ()=>number {

  var _count: number = 0;

  var increment: ()=>number = function(): number {
    _count += 1;
    return _count;
  }

  return increment;
}());

func is a function that returns a function that returns a number. I've set its type to '()=>()=>number', but the compiler doesn't like that. I know this isn't the most practical use of TypeScript, but does anyone have any thoughts for fixing the compile error?

Answer

David Sherret picture David Sherret · Sep 3, 2015

You could leave the code as-is. TypeScript already figures out that the types of all the variables in your code by looking at the initial assignment. Hover over the variables and you will see the types it's figured out.

The main problem in the code is that the type of func is incorrect. This:

var func: () => () => number = ...

...should be this:

var func: () => number = ...

Note there's no need for the extra () => because it's not a function that returns a function that returns a number. It's only a function that returns a number.


By the way, if you really want to explicitly type everything, here's another solution:

var func: () => number = (() => {

    var private_count: number = 0;

    var increment: () => number = () => {
        private_count += 1;
        return private_count;
    };

    return increment;
})();

But I would recommend just using implicit types (as long as they're not implicit any types), but that's just a personal preference:

var func = (() => {

    var private_count = 0;

    var increment = () => {
        private_count += 1;
        return private_count;
    };

    return increment;
})();