Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coding a closure in TypeScript

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?

like image 802
MatthewScarpino Avatar asked Sep 03 '15 15:09

MatthewScarpino


2 Answers

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;
})();
like image 173
David Sherret Avatar answered Oct 07 '22 21:10

David Sherret


Here it is:

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

    var _count: number = 0;

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

        _count += 1;

        return _count;
    }

    return increment;
})();

But adding an interface makes it easier.

interface Increment {
    (): number;
}

var func = ((): Increment => {

    var _count: number = 0;

    var increment: Increment = function () {

        _count += 1;

        return _count;
    }

    return increment;
})();
like image 32
thoughtrepo Avatar answered Oct 07 '22 20:10

thoughtrepo