Почему необходимо «объявить переменную угловую» при использовании Typescript с AngularJS? - PullRequest
1 голос
/ 08 мая 2019

У меня есть функциональное приложение 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.module или ng.module не происходит вообще.

Я уверен, что пробовал другие вещи, но единственный способ, которым я когда-либо смог заставить вещи работать, это с этим declare var angular;

Все это прекрасно работает, но это, конечно, пахнет плохо для меня.Почему я должен это сделать?Что я делаю неправильно?Есть ли лучший способ сделать это?


Подробности:

  • Visual Studio 2017/2019
  • TypeScript 3.3
  • SystemJS ((не требуетсяJS)
  • 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 Ответ

1 голос
/ 08 мая 2019

Ваши типы Typescript, @types/angular, найдите переменную angular, к которой нужно присоединить их типы.

Обычно вы импортировали бы angular следующим образом: import angular from "angular", и типы применялись бы к только что созданной переменной angular, и все работало бы просто отлично.

Однако вы уже загружаете Angular глобально в свой HTML <script>. В этом случае вам не нужно import angular from "angular", потому что тогда вы загрузите Angular более одного раза, и все может сломаться.

Написав declare var angular, вы просто говорите Typescript, чтобы он доверял вам, что он существует, даже если он не видел его импортированным в область действия этого файла.

Это значит

  • Машинопись не будет жаловаться на неопределенность Angular.
  • @types/angular присоединится к вашей переменной angular.

Когда вы доберетесь до времени выполнения, предполагая, что angular действительно существует на window, тогда оно будет работать.

Это проблема, которая будет требоваться при переходе к пакетам, таким как Webpack или SystemJS. После того как вы удалите глобальный Angular из index.html <script>, вы можете импортировать в файлы TS и удалить declare var.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...