Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

angularjs - After upgrading TypeScript, Angular controller registration now fails to compile

We were using TypeScript 2.2. After upgrading to 2.4, we now get this on compilation:

error TS2345: Argument of type 'typeof TopMenuController' is not assignable to parameter of type 'Injectable<IControllerConstructor>'. Type 'typeof TopMenuController' is not assignable to type '(string | (new (...args: any[]) => IController) | ((...args: any[]) => void | IController))[]'. Property 'push' is missing in type 'typeof TopMenuController'.

tscontrollersTopMenuController.ts(2,18): error TS2559: Type 'TopMenuController' has no properties in common with type 'IController'.

I don't understand the first error and Googling it has been difficult. I'm only asking for assistance with the first error. (I'm getting the second error due to my attempts to resolve the first). Here's the controller:

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

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

And this is how it is registered.

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

How do i modify my controller definition or its registration so our code compiles again?

(Removing the implements angular.IController bit removes the second error, but the first remains)

Edit: I found this bug

question from:https://stackoverflow.com/questions/44803945/after-upgrading-typescript-angular-controller-registration-now-fails-to-compile

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Since all of the properties of IController are optional, I believe the errors you are seeing are a result of the new checking for "Weak Types" in TypeScript 2.4. Check this link from Microsoft for details. Also check this related Github issue.

Some relevant quotes from Microsoft:

In TypeScript 2.4, we’re adding a similar check for what we call weak types. Any type that contains only optional properties is considered a weak type since it provides few restrictions on what can be assigned to it.

...

In TypeScript 2.4, it’s now an error to assign anything to a weak type when there’s no overlap in properties.

...

You can think of this as TypeScript “toughening up” the weak guarantees of these types to catch what would otherwise be silent bugs.

Since this is a breaking change, you may need to know about the workarounds which are the same as those for strict object literal checks:

  1. Declare the properties if they really do exist.
  2. Add an index signature to the weak type (i.e. [propName: string]: {}).
  3. Use a type assertion (i.e. opts as Options).

Edit: Based on this information, a simple solution would then be to implement one of the methods defined in IController. For example, as mentioned by @Amy in the comments, you could just define an empty $onInit method in your controller.

Edit: For the sake of completeness, here's the full code:

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

  $onInit() { }

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...