web-dev-qa-db-fra.com

Après la mise à niveau de TypeScript, Angular angulaire ne parvient plus à compiler

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

erreur TS2345: l'argument de type "typeof TopMenuController" n'est pas attribuable au paramètre de type "Injectable <IControllerConstructor>". Le type 'typeof TopMenuController' n'est pas attribuable au type '(chaîne | (nouveau (... 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 la recherche sur Google a été difficile. Je demande seulement de l'aide pour la première erreur. (J'obtiens la deuxième erreur en raison de mes tentatives pour résoudre la première). 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 ainsi qu'il est enregistré.

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

Comment puis-je modifier la définition de mon contrôleur ou son enregistrement pour que notre code se compile à nouveau?

(Suppression du implements angular.IController bit supprime la deuxième erreur, mais la première reste)

Edit: J'ai trouvé ce bug

38
Amy

Étant donné que toutes les propriétés de IController sont facultatives, je pense que les erreurs que vous voyez sont le résultat de la nouvelle vérification des "types faibles" dans TypeScript 2.4. Vérifiez ce lien de Microsoft pour plus de détails. Vérifiez également ce problème lié à 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 attribué.

...

Dans TypeScript 2.4, c'est désormais une erreur d'attribuer quoi que ce soit à un type faible lorsqu'il n'y a pas de chevauchement dans les propriétés.

...

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

Puisqu'il s'agit d'un changement de rupture, vous devrez peut-être connaître les solutions de contournement qui sont les mêmes que celles des vérifications strictes du littéral d'objet:

  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'est-à-dire 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 un $onInit méthode 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) {
  }
}
42
Frank Modica

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

  • implémentation de IController

  • ajoutez ce code avant le 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)
}

Happy Coding

7
UniCoder

l'ajout du code suivant a résolu le problème

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