MatthewScarpino
MatthewScarpino

Reputation: 5936

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?

Upvotes: 12

Views: 30867

Answers (3)

Laquio
Laquio

Reputation: 39

I did try this and it works!

file1.ts

export var Mvar = (() => {
    var private_arry = [];
    function pushfn(val):any {
      return private_arry.push(val);
    }
    function countfn():number {
      return private_arry.length;
    }
    function setfn(val):void {
      private_arry = null;
      private_arry = val;
    }
    function getfn(val?:number):any {
      if(val!==undefined) {
        return private_arry[val];
      }
      return private_arry;
    }
    return {
      push:pushfn,
      count:countfn,
      set:setfn,
      get:getfn
    }
})()

file2.ts

import { Mvar } from '../../shared/file1';

ngOnInit() {

console.log("private var: " + Mvar.push("e1"));
console.log("private count: " + Mvar.count());
console.log("private get: " + Mvar.get());

...
}

Upvotes: 0

David Sherret
David Sherret

Reputation: 106850

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;
})();

Upvotes: 20

thoughtrepo
thoughtrepo

Reputation: 8383

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;
})();

Upvotes: 1

Related Questions