简体   繁体   English

升级 TypeScript 后,Angular 控制器注册现在无法编译

[英]After upgrading TypeScript, Angular controller registration now fails to compile

We were using TypeScript 2.2.我们使用的是 TypeScript 2.2。 After upgrading to 2.4, we now get this on compilation:升级到 2.4 后,我们现在在编译时得到这个:

error TS2345: Argument of type 'typeof TopMenuController' is not assignable to parameter of type 'Injectable<IControllerConstructor>'.错误 TS2345:“typeof TopMenuController”类型的参数不可分配给“Injectable<IControllerConstructor>”类型的参数。 Type 'typeof TopMenuController' is not assignable to type '(string | (new (...args: any[]) => IController) | ((...args: any[]) => void | IController))[]'.类型 'typeof TopMenuController' 不能分配给类型 '(string | (new (...args: any[]) => IController) | ((...args: any[]) => void | IController))[ ]'。 Property 'push' is missing in type 'typeof TopMenuController'. “typeof TopMenuController”类型中缺少“push”属性。

ts\\controllers\\TopMenuController.ts(2,18): error TS2559: Type 'TopMenuController' has no properties in common with type 'IController'. ts\\controllers\\TopMenuController.ts(2,18):错误 TS2559:“TopMenuController”类型与“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) (删除implements angular.IController位删除了第二个错误,但第一个仍然存在)

Edit: I found this bug编辑:我发现了这个错误

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.由于IController所有属性都是可选的,我相信您看到的错误是 TypeScript 2.4 中新检查“弱类型”的结果。 Check this link from Microsoft for details.有关详细信息,请查看Microsoft 的此链接 Also check this related Github issue .还要检查这个相关的 Github 问题

Some relevant quotes from Microsoft:微软的一些相关引述:

In TypeScript 2.4, we're adding a similar check for what we call weak types.在 TypeScript 2.4 中,我们为所谓的弱类型添加了类似的检查。 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.在 TypeScript 2.4 中,当属性没有重叠时,现在将任何内容分配给弱类型都是错误的。

... ...

You can think of this as TypeScript “toughening up” the weak guarantees of these types to catch what would otherwise be silent bugs.您可以将其视为 TypeScript “强化”这些类型的弱保证,以捕获原本会是无声的错误。

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 (ie [propName: string]: {}).为弱类型添加索引签名(即 [propName: string]: {})。
  3. Use a type assertion (ie opts as Options).使用类型断言(即选择作为选项)。

Edit: Based on this information, a simple solution would then be to implement one of the methods defined in IController .编辑:根据此信息,一个简单的解决方案是实现IController定义的方法之一。 For example, as mentioned by @Amy in the comments, you could just define an empty $onInit method in your controller.例如,正如@Amy 在评论中提到的,您可以在控制器中定义一个空的$onInit方法。

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) {
  }
}

I also faced the same issue which I got resolved by我也遇到了同样的问题,我得到了解决

  • implementing IController实现IController

  • add this code before constructor ( or anywhere in code this is my preference ) $onInit = () => { };在构造函数之前添加此代码(或代码中的任何位置,这是我的偏好$onInit = () => { };

here is the full code, Hope this will give a clear view这是完整的代码,希望这会给你一个清晰的视图

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

Happy Coding快乐编码

添加以下代码修复了问题

$onInit = () => { };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM