如何在TypeScript中创建可以在纯JavaScript中使用的全局命名空间/类?

时间:2017-01-19 21:21:25

标签: javascript angular typescript

我的TypeScript和纯JavaScript代码需要共享命名空间和一些数据。 TypeScript应该“准备”命名空间,外部JS提供数据,TypeScript处理它。

上下文是Angular 2应用程序。装货单是:

  1. Angular 2应用程序及其JavaScript启动
  2. 自定义外部JavaScript文件是从外部源(JSONP样式)
  3. 动态加载的
  4. Angular 2应用程序对加载的JS文件生成的数据进行进一步处理
  5. 目前在外部JavaScript文件中我正在做这样的事情:

    if (typeof Blog === 'undefined')
    {
        Blog = {
            Posts: []
        }
    }
    // ...
    Blog.Posts.push(post);
    

    在我的Angular 2应用程序中,这个JavaScript文件正在动态加载,然后访问该值:

    declare var Blog: any;
    ...
    let firstPost = Blog.Posts[0];
    

    这样可行,我可以访问外部JS放置的数据。

    现在我想尽可能减少JavaScript部分。所以我想BlogPosts的声明移到TypeScript ,最好是以强类型方式在那里使用。

    所以我希望我的JavaScript看起来像这样:

    // ...
    Blog.Posts.push(post);
    

    请注意Blog缺少的声明。我在TypeScript中尝试过类似的东西:

    declare var Blog: BlogClass; // <- this is probably wrong, can be changed to anything necessary to make it work...
    // ...
    Blog = new BlogClass();
    

    但显然它并不那么容易。我的Angular 2应用程序死于我,带有一般错误消息。该错误是由Blog = new BlogClass()引起的。

    有关如何解决此问题的任何提示?

1 个答案:

答案 0 :(得分:2)

declare表示声明的事物必须在其他地方定义。

declare var Blog: BlogClass;

不会在生成的javascript中生成任何代码,因此这个分配

Blog = new BlogClass(); 

在运行时失败,因为Blog不存在。

当您删除declare时,此行会显示在生成的代码中:

var Blog;

但是,它不一定在全局范围内创建var Blog - 当您将typescript代码编译为模块时,它将在模块内创建,并且将无法访问外部JavaScript代码,除非您通过从typescript模块导出它并在javacsript代码中导入该模块。

确保在全局范围内创建对象的最简单(但有点脏)的方法是明确地这样做:

(window as any).Blog = new BlogClass();