Javascript 打字稿错误:当类包含初始化的属性时,“超级”调用必须是构造函数中的第一条语句

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31701266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:03:53  来源:igfitidea点击:

Typescript error : A 'super' call must be the first statement in the constructor when a class contains initialized properties

javascriptangularjsbackbone.jstypescript

提问by KinyoriDeStephen

I have the following typescript errors in my project.. let me share a sample so you can see what am dealing with.

我的项目中有以下打字稿错误..让我分享一个示例,以便您了解正在处理的内容。

module CoreWeb {
export class Controller implements IController {
    public $q;
    public $rootScope;
    public $scope:ng.IScope;
    public $state:ng.ui.IStateService;
    public $translate:ng.translate.ITranslateService;
    public appEvents;
    public commonValidationsService;
    public defaultPagingOptions = {
        currentPage: 1,
        pageSize: 10,
        totalServerItems: 0,
        maxSize: 5
    };
    public detailModelName:string;
    public filter:string;
    public listModelName:string;
    public mode;
    public modelDataService;
    public modelDefaultProperty:string;
    public ngDialog;
    public notificationsService;
    public pagingOptions:IPagingOptions;
    public selectionStatus:boolean;
    public serviceCreateFunction:string;
    public serviceGetAllCanceller:ng.IDeferred<any>;
    public serviceGetAllFunction:string;
    public serviceGetOneFunction:string;
    public serviceUpdateFunction:string;
    public showInactive:boolean;
    public tableAction:number;
    public tableActions:ITableAction[];
    public titleDataFactory;
    public validationOptions;
    public validationRules;
    public orderBy = null;
    public orderType = null;
    constructor(
        $q:ng.IQService,
        $rootScope,
        $scope:ng.IScope,
        $state,
        $translate:ng.translate.ITranslateService,
        appEvents,
        commonValidationsService,
        detailModelName:string,
        listModelName:string,
        modelDataService,
        modelDefaultProperty:string,
        ngDialog,
        notificationsService,
        serviceCreateFunction:string,
        serviceGetAllFunction:string,
        serviceGetOneFunction:string,
        serviceUpdateFunction:string,
        titleDataFactory
    ) {
        this.$q = $q;
        this.$rootScope = $rootScope;
        this.$scope = $scope;
        this.$state = $state;
        this.$translate = $translate;
        this.appEvents = appEvents;
        this.commonValidationsService = commonValidationsService;
        this.detailModelName = detailModelName;
        this.listModelName = listModelName;
        this.modelDataService = modelDataService;
        this.modelDefaultProperty = modelDefaultProperty;
        this.ngDialog = ngDialog;
        this.notificationsService = notificationsService;
        this.serviceCreateFunction = serviceCreateFunction;
        this.serviceGetAllCanceller = $q.defer();
        this.serviceGetAllFunction = serviceGetAllFunction;
        this.serviceGetOneFunction = serviceGetOneFunction;
        this.serviceUpdateFunction = serviceUpdateFunction;
        this.titleDataFactory = titleDataFactory;

        this.mode = $rootScope.modeEnum.none;
        this.pagingOptions = this.defaultPagingOptions;
        this.selectionStatus = false;
        this.showInactive = false;
        this.tableAction = null;
        this.tableActions = [
            {id: 1, name: "Activate"},
            {id: 2, name: "Deactivate"}
        ];
        this.validationOptions = {showErrors: commonValidationsService.modes.property, showNotification: true};

        this.activate();
    }

This is the class that extends the controller class.. one among many others

这是扩展控制器类的类......其中之一

declare var App: ng.IModule;

module CoreWeb {
    export class EntityMasterController extends Controller {
        private currenciesDataSet;
        private entity: IEntityMasterModel;
        private merchandisingConstants;
        private typeAheadOptions;

    constructor(
        $q:ng.IQService,
        $rootScope,
        $scope:ng.IScope,
        $state,
        $translate:ng.translate.ITranslateService,
        appEvents,
        commonValidationsService,
        entityDataService,
        merchandisingConstants,
        ngDialog,
        notificationsService,
        titleDataFactory
    ) {
        this.merchandisingConstants = merchandisingConstants;
        super(
            $q,
            $rootScope,
            $scope,
            $state,
            $translate,
            appEvents,
            commonValidationsService,
            "entity",
            null,
            entityDataService,
            "name",
            ngDialog,
            notificationsService,
            "createEntity",
            "getCurrentEntity",
            "getEntity",
            "updateEntity",
            titleDataFactory
        );
    }

Now, if I initialize the merchandisingConstantsbefore the super call like done above.. I get the following error during gulp and my page does not display anything.. A supercall must be the first statement in the constructor when a class contains initialized properties or has parameter properties. I have tried all ways I can think off to fix this errors any idea of how I can go about this?

现在,如果我merchandisingConstants像上面那样在 super 调用之前初始化.. 我在 gulp 期间收到以下错误并且我的页面不显示任何内容..super当类包含初始化的属性或具有参数时,调用必须是构造函数中的第一条语句特性。我已经尝试了所有我能想到的方法来解决这个错误,我知道如何解决这个问题吗?

回答by Fenton

When you extend a class, your constructor:

当你扩展一个类时,你的构造函数:

  1. Must call super()
  2. Must do that before it does anything else
  1. 必须打电话 super()
  2. 在它做任何其他事情之前必须这样做

In your instance, you just need to re-order things:

在您的实例中,您只需要重新排序:

declare var App: ng.IModule;

module CoreWeb {
    export class EntityMasterController extends Controller {
        private currenciesDataSet;
        private entity: IEntityMasterModel;
        private merchandisingConstants;
        private typeAheadOptions;

    constructor(
        $q:ng.IQService,
        $rootScope,
        $scope:ng.IScope,
        $state,
        $translate:ng.translate.ITranslateService,
        appEvents,
        commonValidationsService,
        entityDataService,
        merchandisingConstants,
        ngDialog,
        notificationsService,
        titleDataFactory
    ) {
        // Must be first
        super(
            $q,
            $rootScope,
            $scope,
            $state,
            $translate,
            appEvents,
            commonValidationsService,
            "entity",
            null,
            entityDataService,
            "name",
            ngDialog,
            notificationsService,
            "createEntity",
            "getCurrentEntity",
            "getEntity",
            "updateEntity",
            titleDataFactory
        );

        this.merchandisingConstants = merchandisingConstants;
    }

回答by Pointy

This is quite a hack, but it is a simple workaround to the problem:

这是一个相当大的黑客,但它是解决问题的简单方法:

    super(
        (this.merchandisingConstants = merchandisingConstants, $q),
        $rootScope,
        $scope,
        $state,
        $translate,
        appEvents,
        commonValidationsService,
        "entity",
        null,
        entityDataService,
        "name",
        ngDialog,
        notificationsService,
        "createEntity",
        "getCurrentEntity",
        "getEntity",
        "updateEntity",
        titleDataFactory
    );

That uses the somewhat weird and not-often-useful JavaScript ,operator to stuff the assignment in there as a side effect. You could do it with any of the parameters, really, but I did it with the first one. The comma operator — which is not the sameas the comma that separates arguments to a function, even though of course it's exactly the same character — lets you string together a list of expressions, all of which will be evaluated. Only the last one is used as the value of the overall expression.

这使用了有点奇怪且不常用的 JavaScript,运算符来填充赋值作为副作用。你可以用任何参数来做,真的,但我用第一个参数做到了。逗号运算符——它分隔函数参数的逗号不同,尽管它当然是完全相同的字符——允许您将表达式列表串在一起,所有这些都将被评估。只有最后一个用作整个表达式的值。

Thus, by doing that, you do your assignment while the argument list is being evaluated. The value of the first parameter will still be $q, but the assignment will happen too, before the function call to super()is made.

因此,通过这样做,您可以在评估参数列表时进行分配。第一个参数的值仍然是$q,但赋值也会在调用函数之前发生super()