如何在typescript

时间:2016-04-05 21:31:30

标签: variables typescript global

我需要让“tokens”成为一个全局变量,它将在第一次调用时使用init()函数进行初始化。

Q1。如何使用init()初始化变量?在TypeScript中初始化全局变量的最佳实践是什么?

Q2。由于此变量是从json文件初始化的,如何在应用程序的生命周期内初始化一次?因此,如果我在不同的文件中导入此变量,我不想再次读取json文件。

export var tokens: Token[] = [];

function init() {
    if (tokens) return; // already initialized
    let tokensJson = fs.readFileSync("./lib/data/tokens.json", "utf8");
    let tokensData = JSON.parse(tokensJson);
    for (var i = 0; i < tokensData.length; i++) {
        tokens.push(new Token(tokensData[i].name, tokensData[i].type));
    }
}

客户代码:

file1.ts

import { tokens } from "./tokens";
for (var i = 0; i < tokens.length; i++) 
    ...

file2.ts

import { tokens } from "./tokens";
for (var i = 0; i < tokens.length; i++) 
    ...

我非常感谢你能给我一个创意全局或静态模块变量的想法或最佳模式,这些变量将被初始化一次但可以在TypeScript中的不同文件中使用。

1 个答案:

答案 0 :(得分:1)

模块的顶级代码只执行一次 - 第一次加载模块时。至少CommonJS模块的情况如此,但我认为其他类型也是如此。

如果您第二次导入模块,模块定义中的脚本将不会再次执行,并且将重新使用第一次运行的返回导出。

这意味着你可以这样做:

export var tokens: Token[] = [];

function init() {
    let tokensJson = fs.readFileSync("./lib/data/tokens.json", "utf8");
    let tokensData = JSON.parse(tokensJson);
    for (var i = 0; i < tokensData.length; i++) {
        tokens.push(new Token(tokensData[i].name, tokensData[i].type));
    }
}

init()

或者您甚至可以省略init函数声明并将内容直接放入模块中。如果您不喜欢init名称但仍希望确定临时变量的范围,请使用立即调用的函数。

在您的情况下,单个表达式也可以起作用:

export var tokens = 
  JSON.parse(fs.readFileSync("./lib/data/tokens.json", "utf8"))
  .map(td => new Token(td.name, td.type));