web-dev-qa-db-ja.com

TypeScriptのアップグレード後、Angularコントローラーの登録がコンパイルに失敗するようになりました

TypeScript 2.2を使用していました。 2.4にアップグレードすると、コンパイル時に次のようになります。

エラーTS2345:タイプ 'typeof TopMenuController'の引数は、タイプ 'Injectable <IControllerConstructor>'のパラメーターに割り当てることができません。タイプ 'typeof TopMenuController'は、タイプ '(string |(new(... args:any [])=> IController)|((... args:any [])=> void | IController))[ ] '。タイプ 'typeof TopMenuController'にプロパティ 'Push'がありません。

ts\controllers\TopMenuController.ts(2,18):エラーTS2559:タイプ 'TopMenuController'には、タイプ 'IController'と共通のプロパティがありません。

私は最初のエラーを理解しておらず、グーグルでそれをするのは困難でした。私は最初のエラーについてのみ支援を求めています。 (最初のエラーを解決しようとするため、2番目のエラーが表示されます)。コントローラーは次のとおりです。

export class TopMenuController implements angular.IController {
    static $inject = ["$templateCache", "Restangular"];

    constructor(
        private readonly $templateCache: angular.ITemplateCacheService,
        private readonly restangular: Restangular.IElement) {
    }
}

これが登録方法です。

angular.module("ngApp")
    .config(Configuration.TemplateCacheConfigurator)
    .controller("topMenuController", Controllers.TopMenuController)

コントローラー定義またはその登録を変更して、コードを再度コンパイルするにはどうすればよいですか?

implements angular.IControllerビットは2番目のエラーを削除しますが、最初のエラーは残ります)

編集:見つけました このバグ

38
Amy

IControllerのプロパティはすべてオプションであるため、表示されているエラーは、TypeScript 2.4の「弱い型」の新しいチェックの結果であると考えています。詳細については、 Microsoftのこのリンク を確認してください。 これに関連するGithubの問題 も確認してください。

Microsoftからの関連する引用:

TypeScript 2.4では、弱い型と呼ばれるものに対して同様のチェックを追加しています。オプションのプロパティのみを含むタイプは、割り当て可能なものにほとんど制限がないため、弱いタイプと見なされます。

...

TypeScript 2.4では、プロパティに重複がない場合に弱いタイプに何かを割り当てるとエラーになります。

...

これは、TypeScriptがこれらの型の弱い保証を「強化」して、そうでなければサイレントバグをキャッチするものと考えることができます。

これは重大な変更であるため、厳密なオブジェクトリテラルチェックの場合と同じ回避策について知る必要がある場合があります。

  1. 本当に存在する場合は、プロパティを宣言します。
  2. 弱いタイプにインデックス署名を追加します(つまり、[propName:string]:{})。
  3. 型アサーションを使用します(つまり、オプションとして選択します)。

Edit:この情報に基づいた簡単な解決策は、IControllerで定義されたメソッドの1つを実装することです。たとえば、コメントで@Amyが言及したように、空の$onInitコントローラーのメソッド。

Edit:完全を期すために、ここに完全なコードがあります:

export class TopMenuController implements angular.IController {
  static $inject = ["$templateCache", "Restangular"];

  $onInit() { }

  constructor(
      private readonly $templateCache: angular.ITemplateCacheService,
      private readonly restangular: Restangular.IElement) {
  }
}
42
Frank Modica

私も解決したのと同じ問題に直面しました

  • IControllerの実装

  • コンストラクターの前にこのコードを追加します(またはコード内の任意の場所がこれです$onInit = () => { };

ここに完全なコードがあります、これが明確なビューを提供することを願っています

module MyApp {
    export class HomeController implements angular.IController {
        $onInit = () => { };
        user: string;
        constructor() {
            this.user = "mali";
        }
    }
    angular.module('app').controller('homeController', MyApp.HomeController)
}

ハッピーコーディング

7
UniCoder

次のコードを追加すると問題が修正されました

$onInit = () => { };
0
Nico