【问题标题】:TypeScript how to declare global variable in every file?TypeScript如何在每个文件中声明全局变量?
【发布时间】:2019-01-12 14:25:05
【问题描述】:

我喜欢定义一个全局可用的助手

global.p = console.log.bind(console)

所以我可以使用p('some message') 而不是console.log('some message')

但 TypeScript 抱怨 p 未定义。有没有办法告诉 TypeScript 编译器每个文件中都有一个全局变量 p

【问题讨论】:

  • 从某个文件导入p 函数有什么缺点?为什么必须是全球性的?
  • 因为我有 TypeScript linter 可以捕获所有未使用的变量,所以你不能只导入 p 并将它留在那里,它必须被使用或删除。另外,我不想在每个文件中都添加import { p } from xxx
  • 我认为只在使用时导入函数是一件好事。从长远来看,您和您项目的其他维护者将更加头疼全局函数。以某种方式导入依赖项对可维护性有很大帮助
  • 好坏取决于项目。建造摩天大楼和小屋需要不同的技术。就我而言,我最关心开发速度并希望快速制作原型。所以,就我而言,隐式全局变量要好得多。

标签: typescript


【解决方案1】:

我想我知道你想要做什么——你想让 typescript 明白 p 变量是在全局范围内设置的,而不必在每个文件中都设置 import { p } from ...

如果我没记错的话,你需要做的就是做一个环境声明:

declare const p: (message: string) => void // or whatever

这不必在每个文件中声明。将其放入名为 typings/ 的文件夹中的 d.ts 文件中,然后将该文件包含在您的 tsconfig 中:

"include": [
    "typings/**/*",
    ...
],

注意:您的 d.ts 文件不能导入任何其他模块。但它可以使用在其他 d.ts 文件中声明的其他环境类型,而无需导入它们。如果您导入某些内容,那么 typescript 不会将您的文件视为环境声明并且它将不起作用。

【讨论】:

  • 我将此作为社区 wiki 答案。如果我写的内容有任何错误,请在参考文献中更正。这完全不在我的脑海中,可能不是 100% 准确的。但这是朝着正确方向发展的一点。
【解决方案2】:

明智的做法是抽象日志记录,这样您的程序中就不会出现直接依赖于console.log 的代码。

你可以声明它已经存在于全局:

declare var p: (message: any, ...additionals: any[]) => void;

但如果你必须把它放在每个文件中,你也可以:

import { p } from './logging';

通过使用您的 console.log 包装器创建一个日志记录模块。

【讨论】:

  • 对不起,我没明白。添加这一行import { p } from './logging'; 正是我想要避免的。我不想把它放在每个文件中。
  • @AlexeyPetrushin 为什么要避免这种情况?这正是 typescript 想要强制执行的:使您的依赖关系又名 imports 尽可能明确,这样您就知道您正在使用什么以及它来自哪里。地球人只是把水弄混了。
  • 我们如何避免将declare 放在每个文件中并且也不使用导入?
【解决方案3】:

import {Injectable} from '@angular/core';

@Injectable()
export class GlobalStatus {
  private _status : any;
  constructor() {
    this._status = {
      "GlobaConfigVersion": "0.0.0"
    }
  }
  
  getStatusValue(valKey: string): any {
    return this._status[valKey];
  }
  setStatusValue(valKey: string, theStatus: any): any {
    this._status[valKey] = theStatus;
  }
}

这是我用于全局配置的服务。然后我可以通过这种方式设置/获取全局变量:

import { GlobalStatus } from './globalStatus.service';

//setter
this.globalStatus.setStatusValue("yourValue", value)

// getter
this.globalStatus.getStatusValue("yourValue")

【讨论】:

  • 这确实可以让您管理全局变量,但这不是实际上(尽管有标题)OP 想要的。见芬顿的回答。
  • 是的,对不起,我已经回答了标题。但是我认为这应该是管理全局变量的正确方法。我必须删除这个答案? =)
  • 实际上,我相信在接下来的几个月里,人们会发现它很有用,并会因为问题的标题而投票赞成。我个人会留下它,其他人可能会提出其他意见。如果你突然收到一票否决票,你就会知道该怎么做:)
【解决方案4】:

如果你只是想告诉 TypeScript 对你的 p 变量没问题,你可以在文件的开头声明它:

declare var p: any;

【讨论】:

  • 当您可以声明正确的接口 (message: any, ...additionals: any[]) => void 时,为什么要将其声明为 any,正如另一个答案中所建议的那样?
  • 不,它不会工作,它只会在单个文件中工作。
猜你喜欢
  • 2020-02-10
  • 2022-01-15
  • 2021-06-17
  • 2019-07-27
  • 2019-01-04
  • 2010-10-30
  • 2016-07-09
  • 1970-01-01
  • 2017-07-12
相关资源
最近更新 更多