简体   繁体   中英

TS2322 - Typescript compilation error with ng.IPromise

When using Angular 1.x in combination with Typescript, I'm facing some problems.

Considering this code:

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

It's compiled by tsc, but I 'm getting the following error:

Type 'IPromise<{}>' is not assignable to type 'IPromise'

I tried to use the more specific IHttpPromise , but it does not do the tricks..

Any idea?

Try casting your data to Server.MyItem :

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

You could also use the generic version of the method:

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

When I was using typescript this is how me and my Sr would implement requests.

First I need two interfaces for my result set from any request. One that extends IHttpPromiseCallbackArg and another for my custom Output. And I always liked to create a third for the actual type that was coming back. In this example I have used Contacts as my factory so I need a IContact interface.

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;
}

Then following I need a Notification Factory and 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;
    }
}

Then in any factory I can inject my Request Helper and call '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;
    }
}

And lastly my controller that would call my factory

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();
    }
}

Hopefully this helps. Also I am upvoting @Franks answer since I am type casting my request as he has stated. Credit to Phxjoe for help, My Sr Developer at the time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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