在AngularJS中使用Typescript时,为什么需要“声明var angular”?

时间:2019-05-08 20:42:05

标签: angularjs typescript systemjs

我有一个正常的AngularJS 1.7应用程序,其中所有代码都用TypeScript编写。但是总有事困扰着我。

在我的app.module.ts文件中,我有点丑陋:
declare var angular;
为了
this.app = angular.module('app'...
进行运行。

我尝试过的事情:

1)用
替换declare var angular; import angular from "angular";
进行编译就很好了,但是浏览器抱怨了
Uncaught (in promise) TypeError: angular_1.default.module is not a function

2)将declare var angular;替换为
import * as angular from "angular";
也可以很好地编译,但是浏览器给出了类似的错误:
Uncaught (in promise) TypeError: angular.module is not a function

3)用
替换declare var angular; import ng from "angular";
然后使用ng.angular.moduleng.module根本不会进行转译。

我确定我已经尝试了其他一些方法,但是唯一可行的方法就是使用declare var angular;

一切正常,但是那对我来说确实很难闻。为什么我必须这样做?我究竟做错了什么?有更好的方法吗?


详细信息:

  • Visual Studio 2017/2019
  • TypeScript 3.3
  • SystemJS(不是RequireJS)
  • AngularJS 1.7.8
  • @ types / angular 1.6.54

package.json

"devDependencies": {
    "@types/angular": "^1.6.54",
    ...
},
"dependencies": {
    "angular": "~1.7.8",
    ...
}

tsconfig.json

{
    "compileOnSave": true,
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "*": [ "node_modules/types/*", "node_modules/*" ],
        },
        "module": "system",
        "target": "es6",
        "sourceMap": true,
        "lib": [ "es6", "dom" ],
        "allowSyntheticDefaultImports": true,
        "outFile": "./app/everything.js",
        "moduleResolution": "node",
        "types": [
            "angular",
            "jquery"
        ]
    },
    "include": ["app/**/*"],
    "exclude": ["node_modules", "lib"],
    "strict": true
}

app.module.ts

declare var angular;
...
export class App {
    app: ng.IModule;

    constructor() {
        this.app = angular.module('app', [
        ...
        ]);
    }

    public run() {
        this.app.run([
        ...
        ]);
        ...
    }

index.html

...
<script src="lib/systemjs/system.js"></script>
<script src="lib/angular/angular.min.js" type="text/javascript"></script>
...
<script src="app/everything.js" type="text/javascript"></script>

<script>
    System.config({
        map: {
            "angular": "lib/angular",
            ...
        },
        packages: {
            "angular": { main: "angular.min.js", defaultExtension: "js" },
            ...
        }
    });
    System.import("app.module")
        .then(function (app) {
            let a = new app.App();
            a.run();

            angular.element(function () {
                angular.bootstrap(document, ['app']);
            });
        });
</script>

1 个答案:

答案 0 :(得分:1)

您的打字稿类型@types/angular寻找angular变量来附加其类型。

通常,您将这样导入angular:import angular from "angular",并且类型将应用于刚刚创建的angular变量,并且一切正常。

但是,您已经在HTML <script>中全局加载了Angular。在这种情况下,您不想import angular from "angular",因为那样的话,您将多次加载Angular,并且事情可能会中断。

通过编写declare var angular,您只是在告诉Typescript相信它的存在,即使尚未将其导入到此文件的范围中。

这是

  • Typescript不会抱怨Angular未定义。
  • @types/angular将附加到变量angular

进入运行时时,假设angular上确实存在window,那么它将起作用。

这是您在移至Webpack或SystemJS之类的捆绑器时将需要的一个问题。从index.html <script>删除全局Angular之后,您可以导入TS文件并删除declare var