angularjs - way - typescript angular 4




Après la mise à niveau de TypeScript, l'enregistrement du contrôleur angulaire ne parvient plus à se compiler (2)

Nous utilisions TypeScript 2.2. Après la mise à niveau vers 2.4, nous obtenons maintenant cette compilation:

erreur TS2345: L'argument de type 'typeof TopMenuController' n'est pas assignable au paramètre de type 'Injectable <IControllerConstructor>'. Type 'typeof TopMenuController' n'est pas assignable à type '(string | (new (... args: any []) => IController) | ((... args: any []) => void | IController)) [ ] ' La propriété 'push' est manquante dans le type 'typeof TopMenuController'.

ts \ controllers \ TopMenuController.ts (2,18): erreur TS2559: Le type 'TopMenuController' n'a aucune propriété en commun avec le type 'IController'.

Je ne comprends pas la première erreur et googler cela a été difficile. Je ne demande que de l'aide pour la première erreur. (Je reçois la deuxième erreur en raison de mes tentatives pour résoudre le premier). Voici le contrôleur:

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

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

Et c'est comme ça qu'il est enregistré.

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

Comment modifier ma définition de contrôleur ou son enregistrement afin que notre code soit à nouveau compilé?

(La suppression du bit implements angular.IController supprime la seconde erreur, mais la première reste)

Edit: J'ai trouvé ce bug


J'ai également fait face au même problème que j'ai résolu par

  • implémenter IController

  • ajoutez ce code avant constructeur ( ou n'importe où dans le code, c'est ma préférence ) $onInit = () => { };

voici le code complet, j'espère que cela donnera une vue claire

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

Heureux codage


Toutes les propriétés d' IController étant facultatives, je pense que les erreurs que vous rencontrez résultent de la nouvelle vérification des "types faibles" dans TypeScript 2.4. Consultez ce lien à partir de Microsoft pour plus de détails. Vérifiez également ce problème lié au Github .

Quelques citations pertinentes de Microsoft:

Dans TypeScript 2.4, nous ajoutons une vérification similaire pour ce que nous appelons les types faibles. Tout type qui ne contient que des propriétés facultatives est considéré comme un type faible car il fournit peu de restrictions sur ce qui peut lui être assigné.

...

Dans TypeScript 2.4, il s’agit désormais d’une erreur d’affecter quelque chose à un type faible lorsque les propriétés ne se chevauchent pas.

...

Vous pouvez penser à ceci comme TypeScript "renforçant" les faibles garanties de ces types pour attraper ce qui serait autrement des bogues silencieux.

Comme il s’agit d’un changement radical, vous devrez peut-être connaître les solutions de contournement identiques à celles des vérifications littérales d’objets strictes:

  1. Déclarez les propriétés si elles existent vraiment.
  2. Ajoutez une signature d'index au type faible (c'est-à-dire [propName: string]: {}).
  3. Utilisez une assertion de type (c.-à-d. Opte comme Options).

Edit: Sur la base de ces informations, une solution simple serait alors d'implémenter l'une des méthodes définies dans IController . Par exemple, comme mentionné par @Amy dans les commentaires, vous pouvez simplement définir une méthode $onInit vide dans votre contrôleur.

Edit: Par souci d'exhaustivité, voici le code complet:

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

  $onInit() { }

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






typescript2.0