TypeScript:如何使现有的命名空间成为全局的?

Posted

技术标签:

【中文标题】TypeScript:如何使现有的命名空间成为全局的?【英文标题】:TypeScript: How can I make an existing namespace global? 【发布时间】:2017-05-11 05:14:51 【问题描述】:

我正在尝试停止使用 TSD 在通过全局变量使用许多库的项目中获取类型定义(如果这很重要,tsconfig.json 中使用了outFile 选项)。特别是,它以这种方式使用 Moment 库。 Moment 提供了its own type definitions 作为 NPM 包的一部分。但是,这些定义并未在全局范围内声明任何内容。请注意,moment 既是 moment.MomentStatic 类型的全局变量,也是类型命名空间。使用 NPM 包,我怎样才能扩大全局范围,使一切都开始工作,因为它现在与从 TSD 获得的旧类型定义一起工作?也就是说,moment 应该在任何文件中全局可用,既可以作为变量,也可以作为类型命名空间。基本上,我想要的是这些方面的东西:

import * as _moment from 'moment';
declare global 
    const moment: _moment.MomentStatic;
    import moment = _moment;

这不能编译:

[ts] Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.
[ts] Import declaration conflicts with local declaration of 'moment'

有解决办法吗?

【问题讨论】:

我认为这可能是一个错误:github.com/Microsoft/TypeScript/issues/13175 即使这个问题得到解决,我如何才能声明一个与导入别名同名的变量? TS 目前不允许这样做。 是否应该声明const moment: _moment.Moment?如果我尝试访问 moment.format 等,我会在控制台中收到 undefined 在什么控制台?节点.js?它仅在非 AMD 和非 CommonJS 环境中分配全局。见unpkg.com/moment@2.17.1 对不起,我错了。 moment 变量的类型应该是 moment.MomentStatic,而不是 moment.Moment 【参考方案1】:

回答我自己的问题。最后,我在一个使用全局变量和outFile 的老式项目中找到了一种增加库类型的方法。我们需要为每个库提供一个单独的.d.ts。例子:

    向 Moment.js 添加与 globals/UMD 的兼容性。为了与 TypeScript 1.x 保持兼容,Moment 的类型定义不包括 export as namespace 行。一个修复此问题的.d.ts 文件(例如,命名为augment.moment.d.ts):

    import * as moment from 'moment';
    export as namespace moment;
    export = moment; 
    

    增加 AngularJS 的类型定义。 augment.angular.d.ts:

    import * as angular from 'angular';
    
    declare module 'angular' 
      interface IRootScopeService 
        $$destroyed: boolean;
      
    
    
    export as namespace angular;
    export as namespace ng;
    export = angular;
    

【讨论】:

听起来不是很奇怪,但我会为这个答案给你甜蜜的爱。

以上是关于TypeScript:如何使现有的命名空间成为全局的?的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?

TypeScript(18): 命名空间

Typescript 中的“声明全局”是啥?

TypeScript:如何在命名空间中使用内部接口

从0开始的TypeScriptの十一:模块和命名空间

从0开始的TypeScriptの十一:模块和命名空间