【问题标题】:fix compile errors of typescript from 2.1.XX to 2.4.XXX修复 typescript 从 2.1.XX 到 2.4.XXX 的编译错误
【发布时间】:2018-10-31 09:35:23
【问题描述】:

我已将我的项目从 typescript 2.1.XX 版本迁移到 2.4.2。下面的文件是生成的 jhipster,当我编译文件时它给了我错误:

错误 TS2345:“() => void”类型的参数不可分配给“IServiceProvider”类型的参数。 类型“() => void”中缺少属性“$get”。

您能帮我找出导致编译错误的原因吗?

  namespace module.system {
    "use strict";

    angular
        .module(module.appName)
       .provider('AlertService', AlertService);

    function AlertService () {
        this.toast = false;
        /*jshint validthis: true */
        this.$get = getService;

        this.showAsToast = function(isToast) {
            this.toast = isToast;
        };

        getService.$inject = ['$timeout', '$sce'];

        function getService ($timeout, $sce) {
            let toast = this.toast,
                alertId = 0, // unique id for each alert. Starts from 0.
                alerts = [],
                timeout = 5000; // default timeout

            return {
                factory: factory,
                isToast: isToast,
                add: addAlert,
                closeAlert: closeAlert,
                closeAlertByIndex: closeAlertByIndex,
                clear: clear,
                get: get,
                success: success,
                error: error,
                info: info,
                warning : warning
            };

            function isToast() {
                return toast;
            }

            function clear() {
                alerts = [];
            }

            function get() {
                return alerts;
            }

            function success(msg, params, position) {
                return this.add({
                    type: 'success',
                    msg: msg,
                    params: params,
                    timeout: timeout,
                    toast: toast,
                    position: position
                });
            }

            function error(msg, params, position) {
                return this.add({
                    type: 'danger',
                    msg: msg,
                    params: params,
                    timeout: timeout,
                    toast: toast,
                    position: position
                });
            }

            function warning(msg, params, position) {
                return this.add({
                    type: 'warning',
                    msg: msg,
                    params: params,
                    timeout: timeout,
                    toast: toast,
                    position: position
                });
            }

            function info(msg, params, position) {
                return this.add({
                    type: 'info',
                    msg: msg,
                    params: params,
                    timeout: timeout,
                    toast: toast,
                    position: position
                });
            }

            function factory(alertOptions) {
                let alert = {
                    type: alertOptions.type,
                    msg: $sce.trustAsHtml(alertOptions.msg),
                    id: alertOptions.alertId,
                    timeout: alertOptions.timeout,
                    toast: alertOptions.toast,
                    position: alertOptions.position ? alertOptions.position : 'top right',
                    scoped: alertOptions.scoped,
                    close: function (alerts) {
                        return closeAlert(this.id, alerts);
                    }
                };
                if(!alert.scoped) {
                    alerts.push(alert);
                }
                return alert;
            }

            function addAlert(alertOptions, extAlerts) {
                alertOptions.alertId = alertId++;
                let that = this;
                let alert = this.factory(alertOptions);
                if (alertOptions.timeout && alertOptions.timeout > 0) {
                    $timeout(function () {
                        that.closeAlert(alertOptions.alertId, extAlerts);
                    }, alertOptions.timeout);
                }
                return alert;
            }

            function closeAlert(id, extAlerts) {
                let thisAlerts = extAlerts ? extAlerts : alerts;
                return closeAlertByIndex(thisAlerts.map(function(e) { return e.id; }).indexOf(id), thisAlerts);
            }

            function closeAlertByIndex(index, thisAlerts) {
                return thisAlerts.splice(index, 1);
            }
        }
    }
 }

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我不确定这段代码之前是如何成功编译的,但我现在可以看到问题所在。如果您在 IDE 中跳转到 provider 方法的声明(或在线查看声明 here),您将看到 provider 需要 IServiceProviderFactory(返回 IServiceProvider 对象的函数) 或IServiceProviderClass(扩展IServiceProvider 的类/构造函数),其中在每种情况下,IServiceProvider 对象至少具有$get 属性。看起来您的 AlertService 旨在成为构造函数,但 TypeScript 无法识别它。 (在.ts 文件中,TypeScript 仅将类识别为可构造的。.js 文件有一些特殊情况。)

    简单的方法是对provider 的参数使用类型断言。这不会检查AlertService 是否是有效的IServiceProvider 构造函数,但如果AlertService 代码是自动生成的并且您希望尽量减少必须对其进行的修补数量,这可能是您的最佳选择。

    // In TypeScript 3.0 or newer, you can replace `any` with `unknown`.
    angular
        .module(module.appName)
       .provider('AlertService', <angular.IServiceProviderClass><any>AlertService);
    

    或者,您可以将AlertService 转换为真正的类。如果我没有犯任何错误,以下应该可以工作:

    namespace module.system {
        "use strict";
    
        class AlertService {
            toast = false;
            $get($timeout, $sce) {
                let toast = this.toast,
                    alertId = 0, // unique id for each alert. Starts from 0.
                    alerts = [],
                    timeout = 5000; // default timeout
    
                return {
                    factory: factory,
                    isToast: isToast,
                    add: addAlert,
                    closeAlert: closeAlert,
                    closeAlertByIndex: closeAlertByIndex,
                    clear: clear,
                    get: get,
                    success: success,
                    error: error,
                    info: info,
                    warning : warning
                };
    
                function isToast() {
                    return toast;
                }
    
                function clear() {
                    alerts = [];
                }
    
                function get() {
                    return alerts;
                }
    
                function success(msg, params, position) {
                    return this.add({
                        type: 'success',
                        msg: msg,
                        params: params,
                        timeout: timeout,
                        toast: toast,
                        position: position
                    });
                }
    
                function error(msg, params, position) {
                    return this.add({
                        type: 'danger',
                        msg: msg,
                        params: params,
                        timeout: timeout,
                        toast: toast,
                        position: position
                    });
                }
    
                function warning(msg, params, position) {
                    return this.add({
                        type: 'warning',
                        msg: msg,
                        params: params,
                        timeout: timeout,
                        toast: toast,
                        position: position
                    });
                }
    
                function info(msg, params, position) {
                    return this.add({
                        type: 'info',
                        msg: msg,
                        params: params,
                        timeout: timeout,
                        toast: toast,
                        position: position
                    });
                }
    
                function factory(alertOptions) {
                    let alert = {
                        type: alertOptions.type,
                        msg: $sce.trustAsHtml(alertOptions.msg),
                        id: alertOptions.alertId,
                        timeout: alertOptions.timeout,
                        toast: alertOptions.toast,
                        position: alertOptions.position ? alertOptions.position : 'top right',
                        scoped: alertOptions.scoped,
                        close: function (alerts) {
                            return closeAlert(this.id, alerts);
                        }
                    };
                    if(!alert.scoped) {
                        alerts.push(alert);
                    }
                    return alert;
                }
    
                function addAlert(alertOptions, extAlerts) {
                    alertOptions.alertId = alertId++;
                    let that = this;
                    let alert = this.factory(alertOptions);
                    if (alertOptions.timeout && alertOptions.timeout > 0) {
                        $timeout(function () {
                            that.closeAlert(alertOptions.alertId, extAlerts);
                        }, alertOptions.timeout);
                    }
                    return alert;
                }
    
                function closeAlert(id, extAlerts) {
                    let thisAlerts = extAlerts ? extAlerts : alerts;
                    return closeAlertByIndex(thisAlerts.map(function(e) { return e.id; }).indexOf(id), thisAlerts);
                }
    
                function closeAlertByIndex(index, thisAlerts) {
                    return thisAlerts.splice(index, 1);
                }
            }
        }
        AlertService.prototype.$get.$inject = ['$timeout', '$sce'];
    
        angular
            .module(module.appName)
           .provider('AlertService', AlertService);
    }
    

    顺便说一句,如果可以的话,我强烈建议您升级到最新版本的 TypeScript(当前为 3.1.4)。一直在进行改进,包括对错误消息的改进,可能会帮助您纠正未来的问题。

    【讨论】:

    • 两种解决方案都有效。感谢您清楚地阐明这两种解决方案。在追逐当前版本时,我仍然持怀疑态度,但这是一个重点。
    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    相关资源
    最近更新 更多