最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I cast a list of JSON objects into a list of TypeScript objects without losing properties on the TypeScript

programmeradmin2浏览0评论

I have this Customer class:

export class Customer {
    id: number;
    pany: string;
    firstName: string;
    lastName: string;

    name(): string {
        if (thispany)
            return thispany;
        if (this.lastName && this.firstName)
            return this.lastName + ", " + this.firstName;
        if (this.lastName)
            return this.lastName;
        if (this.firstName)
            return this.firstName;
        if (this.id > 0)
            return "#" + this.id;
        return "New Customer";
    }
}

In my controller I pull down a list of customers:

export class CustomersController {
    static $inject = ["customerService", "workflowService"];

    ready: boolean;
    customers: Array<Customer>;

    constructor(customerService: CustomerService, workflowService: WorkflowService) {
        customerService.getAll().then(
            (response) => {
                this.customers = response.data;
                this.ready = true;
            },
            () => {
                this.ready = true;
            }
        );
        workflowService.uiCustomer.reset();
    }
}
angular.module("app")
    .controller("CustomersController", ["customerService", "workflowService", CustomersController]);

If it helps, getAll() looks like this:

    getAll(): ng.IHttpPromise<Array<Customer>> {
        return this.http.get("/api/customers");
    }

It's this statement that's causing me grief: this.customers = response.data;

But response.data is strongly typed, so shouldn't it "know" about Customer and name()?

When I do that, of course I am overwriting my strongly typed array with the dumb JSON one, which doesn't have my name() method on it.

So how do I keep my name method without copying every property of every object in the list?

Is this bad design on my part? Having these read-only properties was really mon in C#, but I'm a little new to the javascript world. Should I be using a utility class instead?

My current work-around:

this.customers = response.data.map(customer => {
    return angular.copy(customer, new Customer());
});

Feels wrong to build a whole new array and copy all those fields (in my real project Customer has many more properties).

Edit: I've found a few related SO questions, such as Mapping JSON Objects to Javascript Objects as mentioned by @xmojmr. My question was specific to TypeScript and I was wondering if TypeScript had any facilities of its own that would generate the javascript to make this a non-issue. If that's not the case, and we're sure TypeScript doesn't aim to solve this class of problem, then we can regard this question as a duplicate.

I have this Customer class:

export class Customer {
    id: number;
    pany: string;
    firstName: string;
    lastName: string;

    name(): string {
        if (this.pany)
            return this.pany;
        if (this.lastName && this.firstName)
            return this.lastName + ", " + this.firstName;
        if (this.lastName)
            return this.lastName;
        if (this.firstName)
            return this.firstName;
        if (this.id > 0)
            return "#" + this.id;
        return "New Customer";
    }
}

In my controller I pull down a list of customers:

export class CustomersController {
    static $inject = ["customerService", "workflowService"];

    ready: boolean;
    customers: Array<Customer>;

    constructor(customerService: CustomerService, workflowService: WorkflowService) {
        customerService.getAll().then(
            (response) => {
                this.customers = response.data;
                this.ready = true;
            },
            () => {
                this.ready = true;
            }
        );
        workflowService.uiCustomer.reset();
    }
}
angular.module("app")
    .controller("CustomersController", ["customerService", "workflowService", CustomersController]);

If it helps, getAll() looks like this:

    getAll(): ng.IHttpPromise<Array<Customer>> {
        return this.http.get("/api/customers");
    }

It's this statement that's causing me grief: this.customers = response.data;

But response.data is strongly typed, so shouldn't it "know" about Customer and name()?

When I do that, of course I am overwriting my strongly typed array with the dumb JSON one, which doesn't have my name() method on it.

So how do I keep my name method without copying every property of every object in the list?

Is this bad design on my part? Having these read-only properties was really mon in C#, but I'm a little new to the javascript world. Should I be using a utility class instead?

My current work-around:

this.customers = response.data.map(customer => {
    return angular.copy(customer, new Customer());
});

Feels wrong to build a whole new array and copy all those fields (in my real project Customer has many more properties).

Edit: I've found a few related SO questions, such as Mapping JSON Objects to Javascript Objects as mentioned by @xmojmr. My question was specific to TypeScript and I was wondering if TypeScript had any facilities of its own that would generate the javascript to make this a non-issue. If that's not the case, and we're sure TypeScript doesn't aim to solve this class of problem, then we can regard this question as a duplicate.

Share Improve this question edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Nov 6, 2015 at 23:57 ChristopherChristopher 10.7k14 gold badges78 silver badges99 bronze badges 1
  • Possible duplicate of Mapping JSON Objects to Javascript Objects – xmojmr Commented Nov 7, 2015 at 8:06
Add a ment  | 

1 Answer 1

Reset to default 7

You're exactly right about what is happening. Typing in typescript mainly provides you with piler checking. Under the covers, everything piles to JavaScript which isn't strongly typed.

So, when you say:

getAll(): ng.IHttpPromise<Array<Customer>> {
    return this.http.get("/api/customers");
}

all you are really doing is telling is telling the piler "Hey, I'm pretty sure my api endpoint is going to return an array of Customer objects." But as you know, it really just returns a "dumb JSON" array.

What you could consider doing, is creating an interface that describes the JSON object being returned by the API endpoint. Something like:

interface ICustomer {
    id: number;
    pany: string;
    firstName: string;
    lastName: string;
}

And then getAll() bees:

getAll(): ng.IHttpPromise<Array<ICustomer>> {
    return this.http.get("/api/customers");
}

Then you could have a class who's constructor takes ICustomer as a parameter. Or you could create a class with a static method that takes ICustomer and returns the "name".

Obviously, what you are doing now works, but I think you're right to be looking for something that better municates the intent.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论