尝试调用自定义过滤器会导致“错误 TS2349:无法调用类型缺少调用签名的表达式" [英] Trying to invoke custom filter results in 'error TS2349: Cannot invoke an expression whose type lacks a call signature'

查看:41
本文介绍了尝试调用自定义过滤器会导致“错误 TS2349:无法调用类型缺少调用签名的表达式"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从 Angular 控制器调用自定义过滤器,但出现错误:'无法调用类型缺少调用签名的表达式'.

我在我参与的最后一个项目中是这样实现的,所以我不知道哪里出了问题.

过滤器此时不包含任何逻辑,因为我需要先编译它.

这里是过滤器:

///模块应用{'使用严格';/*** 过滤器型号*/导出类 ModelFilter {公共静态工厂(){返回函数(输入:字符串){控制台日志(输入);返回输入;}}}angular.module('app').filter('modelFilter', [ModelFilter.Factory]);}

及其调用的控制器:

///模块应用{'使用严格';接口 ISearchController {车辆:IVehicles;型号:任意;setVehicles(): 空;updateModels(make: string): void;}类 SearchController 实现 ISearchController {静态 $inject = ['汽车制造服务','车辆模型服务','$过滤器'];构造函数(私人车辆制造服务:车辆制造服务,私家车ModelService:VehicleModelService,私人 $filter: ng.IFilterService,公共车辆:IVehicles,公共模型:任何){this.setVehicles();}setVehicles(): void {this.vehicleMakeService.getVehicles().then((data) => {this.vehicles = 数据;});}updateModels(make: string): void {var test = this.$filter('modelFilter')(make);//此处出错}}angular.module('app').controller('SearchController', SearchController);}

reference.ts:

///<参考路径="./tsd.d.ts"/>//咕噜声开始///<reference path="../app/app.config.ts"/>///<reference path="../app/app.module.ts"/>///<reference path="../app/app.route.ts"/>///<reference path="../app/home/home.controller.ts"/>///<reference path="../app/home/home.route.ts"/>///<reference path="../app/models/vehicles.model.ts"/>///<reference path="../app/results/results.controller.ts"/>///<reference path="../app/results/results.route.ts"/>///<reference path="../app/services/cars.service.ts"/>///<reference path="../app/services/vehicles.make.service.ts"/>///<reference path="../app/services/vehicles.models.service.ts"/>///<reference path="../app/templates/search.controller.ts"/>///<reference path="../app/templates/search.filter.ts"/>//咕噜声结束

tsd.d.ts:

//////<reference path="jquery/jquery.d.ts"/>///<reference path="angular-ui-router/angular-ui-router.d.ts"/>///<reference path="angularjs/angular-resource.d.ts"/>

解决方案

修改后的工作示例:

///模块应用{//添加 <--- 修改!导出接口 MyModelFilter 扩展 ng.IFilterService {(名称:'modelFilter'):(输入:字符串)=>细绳;}/*** 过滤器型号*/导出类 ModelFilter {公共静态工厂(){返回函数(输入:字符串){控制台日志(输入);返回输入;}}}angular.module('app').filter('modelFilter', [ModelFilter.Factory]);}模块应用{类搜索控制器{构造函数(私有 $filter:MyModelFilter){//<--- 修改!}updateModels(make: string): void {var test = this.$filter('modelFilter')(make);}}angular.module('app').controller('SearchController', SearchController);}

问题在于 TypeScript 使用以下定义:

/*** $filter - $filterProvider - ng 模块中的服务** 过滤器用于格式化显示给用户的数据.** 见 https://docs.angularjs.org/api/ng/service/$filter*/接口 IFilterService {(名称:'过滤器'):IFilterFilter;(名称:'货币'):IFilterCurrency;(name: 'number'): IFilterNumber;(名称:'日期'):IFilterDate;(名称:'json'):IFilterJson;(名称:'小写'):IFilterLowercase;(名称:'大写'):IFilterUppercase;(名称:'limitTo'):IFilterLimitTo;(名称:'orderBy'):IFilterOrderBy;/*** 用法:* $过滤器(名称);** @param name 要检索的过滤器函数的名称*/<T>(名称:字符串):T;}

对于this.$filter('modelFilter').这意味着使用最后一条规则(即 (name: string): T;).因此,this.$filter('modelFilter') 属于 ng.IFilterService 类型,而 TypeScript 对您的 ModelFilter 一无所知.>

您可以通过添加一个新接口来解决这个问题,如第一个代码清单所示.

您说原始代码在您的另一个项目中有效,但在我看来,除非以某种方式修改了 reference.ts,否则这不太可能.

I am attempting to invoke a custom filter from an Angular controller but I get the error: 'Cannot invoke an expression whose type lacks a call signature'.

I implemented it like this on the last project I worked on so I am at a loss as to what is wrong.

The filter does not contain any logic at this point as I need to get it compiling first.

Here is the filter:

/// <reference path="../../typings/reference.ts" />

module app {
'use strict';

/**
 * Filter models
 */
export class ModelFilter {
    public static Factory() {
        return function(input: string) {
            console.log(input);
            return input;
        }
    }
}

angular.module('app')
    .filter('modelFilter', [ModelFilter.Factory]);
}

And the controller where its called:

/// <reference path="../../typings/reference.ts" />

module app {
'use strict';

interface ISearchController {
    vehicles: IVehicles;
    models: any;
    setVehicles(): void;
    updateModels(make: string): void;
}

class SearchController implements ISearchController {

    static $inject = [
        'VehicleMakeService',
        'VehicleModelService',
        '$filter'
    ];
    constructor(private vehicleMakeService: VehicleMakeService,
                private vehicleModelService: VehicleModelService,
                private $filter: ng.IFilterService,
                public vehicles: IVehicles,
                public models: any) {

        this.setVehicles();
    }

    setVehicles(): void {
        this.vehicleMakeService.getVehicles().then((data) => {
            this.vehicles = data;
        });
    }

    updateModels(make: string): void {

        var test = this.$filter('modelFilter')(make); // Error here
    }
}
angular.module('app').controller('SearchController', SearchController);
}

reference.ts:

/// <reference path="./tsd.d.ts" />

//grunt-start
/// <reference path="../app/app.config.ts" />
/// <reference path="../app/app.module.ts" />
/// <reference path="../app/app.route.ts" />
/// <reference path="../app/home/home.controller.ts" />
/// <reference path="../app/home/home.route.ts" />
/// <reference path="../app/models/vehicles.model.ts" />
/// <reference path="../app/results/results.controller.ts" />
/// <reference path="../app/results/results.route.ts" />
/// <reference path="../app/services/cars.service.ts" />
/// <reference path="../app/services/vehicles.make.service.ts" />
/// <reference path="../app/services/vehicles.models.service.ts" />
/// <reference path="../app/templates/search.controller.ts" />
/// <reference path="../app/templates/search.filter.ts" />
//grunt-end

tsd.d.ts:

/// <reference path="angularjs/angular.d.ts" />
/// <reference path="jquery/jquery.d.ts" />
/// <reference path="angular-ui-router/angular-ui-router.d.ts" />
/// <reference path="angularjs/angular-resource.d.ts" />

解决方案

Modified working example:

/// <reference path="typings/angularjs/angular.d.ts" />

module app {

    // ADDED <--- MODIFIED!
    export interface MyModelFilter extends ng.IFilterService {
        (name: 'modelFilter'): (input: string) => string;
    }

    /**
     * Filter models
     */
    export class ModelFilter {
        public static Factory() {
            return function(input: string) {
                console.log(input);
                return input;
            }
        }
    }

    angular.module('app')
        .filter('modelFilter', [ModelFilter.Factory]);
}

module app {

    class SearchController {
        constructor(private $filter: MyModelFilter) { // <--- MODIFIED!
        }

        updateModels(make: string): void {
            var test = this.$filter('modelFilter')(make);
        }
    }
    angular.module('app').controller('SearchController', SearchController);
}

The problem is that TypeScript uses the following definition:

/**
 * $filter - $filterProvider - service in module ng
 *
 * Filters are used for formatting data displayed to the user.
 *
 * see https://docs.angularjs.org/api/ng/service/$filter
 */
interface IFilterService {
    (name: 'filter'): IFilterFilter;
    (name: 'currency'): IFilterCurrency;
    (name: 'number'): IFilterNumber;
    (name: 'date'): IFilterDate;
    (name: 'json'): IFilterJson;
    (name: 'lowercase'): IFilterLowercase;
    (name: 'uppercase'): IFilterUppercase;
    (name: 'limitTo'): IFilterLimitTo;
    (name: 'orderBy'): IFilterOrderBy;
    /**
     * Usage:
     * $filter(name);
     *
     * @param name Name of the filter function to retrieve
     */
    <T>(name: string): T;
}

for this.$filter('modelFilter'). It means that the last rule (i.e. <T>(name: string): T;) is used. Consequently, this.$filter('modelFilter') is of type ng.IFilterService and TypeScript does not know anything about your ModelFilter.

You can solve the problem by adding a new interface as shown in the first code listing.

You said that the original code worked in another project of yours but it seems very unlikely to me unless reference.ts was somehow modified.

这篇关于尝试调用自定义过滤器会导致“错误 TS2349:无法调用类型缺少调用签名的表达式"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆