在TypeScript中编写闭包

Coding a closure in TypeScript

本文关键字:闭包 TypeScript      更新时间:2023-09-26

只是为了好玩,我试图在包含闭包的代码中使用TypeScript的强类型。下面是原始JavaScript代码的样子:

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

下面是我用TypeScript实现它的最佳尝试:

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

func是返回一个返回数字的函数的函数。我将其类型设置为'()=>()=>number',但编译器不喜欢这样。我知道这不是TypeScript最实际的用途,但是有没有人对修复编译错误有任何想法?

您可以让代码保持原样。TypeScript已经通过查看初始赋值计算出代码中所有变量的类型。将鼠标悬停在变量上,你会看到它计算出的类型。

代码中的主要问题是func的类型不正确。:

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

…应该是这样:

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

注意这里不需要额外的() =>,因为它不是一个返回返回数字的函数。它只是一个返回数字的函数。


顺便说一下,如果你真的想显式地键入所有内容,这里有另一个解决方案:
var func: () => number = (() => {
    var private_count: number = 0;
    var increment: () => number = () => {
        private_count += 1;
        return private_count;
    };
    return increment;
})();

但我建议只使用隐式类型(只要它们不是隐式any类型),但这只是个人偏好:

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

如下:

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

但是添加一个接口使它更容易。

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

我确实尝试过这个,它工作!

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