【问题标题】:TS2322 - Typescript compilation error with ng.IPromiseTS2322 - ng.IPromise 的 Typescript 编译错误
【发布时间】:2018-06-09 23:56:28
【问题描述】:

将 Angular 1.x 与 Typescript 结合使用时,我遇到了一些问题。

考虑这段代码:

get(id): ng.IPromise<Server.MyItem> {
   return this.$http.get(`${this.baseAddress}/${id}`).then(d => d.data);
}

它是由 tsc 编译的,但我收到以下错误:

类型“IPromise”不可分配给类型“IPromise”

我尝试使用更具体的IHttpPromise,但它并没有起到作用..

有什么想法吗?

【问题讨论】:

    标签: angularjs unit-testing typescript karma-runner


    【解决方案1】:

    尝试将您的数据转换为Server.MyItem

    get(id): ng.IPromise<Server.MyItem> {
       return this.$http.get(`${this.baseAddress}/${id}`).then(d => <Server.MyItem>d.data);
    }
    

    您也可以使用该方法的通用版本:

    get(id): ng.IPromise<Server.MyItem> {
       return this.$http.get<Server.MyItem>(`${this.baseAddress}/${id}`).then(d => d.data);
    }
    

    【讨论】:

    • 没有任何类型可以添加到响应“d”中以节省我们必须转换的时间吗?
    • @illwalkwithyou 由于类型定义了响应类型,我认为你唯一能做的就是使用get 方法的通用版本。我更新了我的答案。
    【解决方案2】:

    当我使用 typescript 时,这就是我和我的 Sr 实现请求的方式。

    首先,我需要两个接口用于来自任何请求的结果集。一个扩展 IHttpPromiseCallbackArg,另一个用于我的自定义输出。而且我总是喜欢为回来的实际类型创建第三个。在这个例子中,我使用 Contacts 作为我的工厂,所以我需要一个 IContact 接口。

    interface ICallback<T> extends ng.IHttpPromiseCallbackArg<T> {
        data?: T;
    }
    interface IOutput<T> {
        Output: T,
        ErrorMsg: string
    }
    interface IContact {
        ContactID: string;
        ContactLastName: string;
        ContactFirstName: string;
        ContactEmail: string;
        ContactPhone: string;
        ContactFullName: string;
        ModifiedBy?: string;
        ModifiedOn?: Date;
        CreatedBy: string;
        CreatedOn: Date;
    }
    

    然后我需要一个 Notification Factory 和 RequestHelper Factory

    export class NotificationFactory {
    
       success = function (msg: string, title?: string): void {
            this.toastr.success(msg, title);
        }
        error = function (msg: string, title?: string): void {
            this.toastr.error(msg, title);
        }
    
        static $inject: Array<string> = ['toastr'];
        constructor(private toastr: ng.toastr.IToastrService) {
            return this;
        }
    }
    export class RequestHelper {
    
        toastSuccess = function (msg: string, title?: string): void {
            this.NotificationFactory.success(msg, title);
        }
        toastError = function (msg: string, title?: string): void {
            this.NotificationFactory.error(msg, title);
        }
    
        private success = (results: ICallback<IOutput<any>>, options: IOptions): any => {
            if (results.data.ErrorMsg) {
                this.NotificationFactory.error(results.data.ErrorMsg);
            }
            if (typeof options.callback === 'function') {
                if (options.showSave && !results.data.ErrorMsg) {
                    this.NotificationFactory.success('Your changes have been saved.');
                }
                return options.callback(results.data);
            }
            if (options.showSave && !results.data.ErrorMsg) {
                this.NotificationFactory.success('Your changes have been saved.');
            }
            return results.data;
        }
        private fail = (err: any, options: IOptions): ng.IPromise<any> => {
            if (options.callingFn !== undefined) {
                this.NotificationFactory.error('There was an error calling ' + options.callingFn + '. details:' + err.statusText);
            }
            return err;
        }
        makeRequest = (request: IRequest, o?: IOptions): ng.IPromise<any> => {
            o = o || {};
            var vm = this;
            return this.$http(request).then((results: ICallback<IOutput<any>>) => {
                    return vm.success(results, o);
                }).catch((err) => {
                    return vm.fail(err, o);
                });
        }
        static $inject: Array<string> = ['$http', '$state', '$stateParams', 'NotificationFactory'];
    
        constructor(private $http: ng.IHttpService, private $state: any, private $stateParams: IMyStateParams, private NotificationFactory: NotificationFactory)     {
            return this;
        }
    }
    

    然后在任何工厂我都可以注入我的请求助手并调用'makeRequest'

    export class ContactsFactory {
        getData = (): ng.IPromise<IOutput<Array<IContact>>> => {
            let req = { method: 'GET', url: '/Contacts/GetContacts?d=' + Date.parse(new Date().toString()).toString() };
            return this.RequestHelper.makeRequest(req, { callingFn: 'ContactsFactory.getData', callback: null, showSave: false });
        }
        getContactByID = (id: string): ng.IPromise<IOutput<Array<IContact>>> => {
            let req = { method: 'POST', url: '/Contacts/GetContactByID', data: { id: id } };
            return this.RequestHelper.makeRequest(req, { callingFn: 'ContactsFactory.getContactByID', callback: null, showSave: false });
        }
    
        static $inject: Array<string> = ['RequestHelper', 'UsersFactory'];
        constructor(private RequestHelper: RequestHelper, private UsersFactory: UsersFactory) {
            return this;
        }
    }
    

    最后是我的控制器,它会调用我的工厂

    export class ContactsController {
        loading: boolean;
        contacts: Array<IContact>;
    
        initialize = (): void => {
            this.loading = true;
            this.ContactsFactory.getData().then((results) =>  {
                    this.contacts = results.Output;
                    this.loading = false;
                });
            });
        }
    
        static $inject: Array<string> = ['ContactsFactory'];
        constructor(private ContactsFactory: ContactsFactory) {
            this.initialize();
        }
    }
    

    希望这会有所帮助。我也赞成@Franks 的回答,因为我按照他的说法输入了我的请求。感谢 Phxjoe 的帮助,我当时的高级开发人员。

    【讨论】:

    • 事实上——到那时——我终于找到了问题所在。如果您遇到此类问题,只需将 IHttpPromise 提取到 var 中,然后返回 yourVar.then(callback)。似乎是打字稿编译器的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 2017-04-02
    • 2014-03-07
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多