HTTP:从JSON对象到Typescript键入断言 [英] HTTP: Type assertion from JSON object to Typescript

查看:138
本文介绍了HTTP:从JSON对象到Typescript键入断言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读接口并输入断言。一直在查看以下页面:

I've reading up on interfaces and type assertion. Been looking at pages like:

  • Typescript parse json with class and interface
  • How do I cast a json object to a typescript class (this one has nothing to do with TS!)
  • Parse complex json objects with Typescript
  • TS doc about interfaces

我已经掌握了它,并且在理解基础知识方面非常简单。虽然:当涉及到HTTP时,我无处可找到如何在我的应用程序中使用的对象中键入JSON对象。

I'm getting the hang of it, and it's pretty straightforward in understanding the basics. Though: Nowhere do I find how to type a JSON object to a object I use in my app, when HTTP is involved.

例如,我有一个教师数组-objects。每位教师都有一个id,名字和一系列学生。我有另一个班级学生,包含他们的属性.....等。

For example, I have an Array of Teacher-objects. Each Teacher has an id, name and an Array of Students. I have another class Students that contain their attributes..... etc.

在这些链接的某处我读到了,除非你需要对一个对象执行动作,它是足以只有一个接口。但除非你想对对象做一些动作,否则你需要一个单独的类?

Somewhere in those links I read that, unless you need to perform actions to an object, it's enough to have just an Interface. But unless you want to do actions to the Object you need a separate class?

我的实际教师课程以......开头:

My actual Teacher class begins with... :

export class Teacher {

    private students: Array<Student>;

    constructor(public id: string, public name: string) {
        this.students = new Array<Student>();
    }

    public getStudents(): Array<Student> {
        return this.students;
    }

}

首先,如何代码看起来好像我想把JS对象强制转换(或断言类型)给一个Teacher对象?

First of all, how would the code look like if I want to cast (or assert the type) the JS object to a Teacher object?

现在我的代码看起来像这样:

Now my code looks something like this:

服务:

getTeachers() {
    return this.http.get('someUrl')
    .map((res: Response) => res.json())
}

组件(Angular 2组件):

Component (Angular 2 Component):

export class ListComponent implements OnActivate {

id: string;
name: string;
teachers: Teacher[];

constructor(public _service: Service, public _router: Router) {

}

routerOnActivate(): void {
    this._service.getTeachers()
        .subscribe(teachers => this.teachers = teachers);
}

我的界面如下所示:

export interface TeacherJSON {
        id: string,
        name: string,
        students: Array<Student>;
}

如果上述界面不足以能够对对象,我该如何前进?我确实知道你可以为你的界面添加方法,如:

If the the above interface is not enough to be able to perform actions on the object, how do I move forward? I did learn that you can add methods to your interface like:

interface Thing {
    a: number;
    b: string;
    foo(s: string, n: number): string;
}

process(x: Thing) {
    return x.foo("abc");
}

我理解上面的例子,但我想http,映射和订阅让我失望,我不知道如何在我的代码中实现它!

I do understand the above example, but I guess the http, mapping and subscribing is throwing me off, and I don't know how to implement it in my code!

推荐答案


所以很明显我需要先将组件中的teacher数组更改为我的界面实例?

So obviously I need to first change my teachers array in the component to an instance of my interface?

没有这样的事情接口的实例。接口是抽象的,它们只存在于TypeScript中,甚至不能编译为JavaScript。你编写它们以在编辑器中获得代码完成和其他好东西;在大型应用程序中帮助您,因此您不必记住每个对象具有的属性和方法。

There's no such thing as an instance of the interface. Interfaces are abstract, they exist in TypeScript only, they don't even compile to JavaScript. You write them to get code completion and other goodies in your editor; to help you in large apps, so you don't have to remember what properties and methods every single object has.

当您必须实例化对象时,接口可以'这样做 - 你将使用一个类,并像往常一样创建属性和方法。在您的示例中执行此操作的正确方法是:

When you have to instantiate an object, interfaces can't do that - you'll use a class, and create properties and methods as usual. Correct way to do this in your example would be:

interface ITeacher{
  id: string,
  name: string,
  students: Array<Student>;
};
class Teacher implements ITeacher {
  id: string,
  name: string,
  students: Array<Student>;
}

在您的情况下,实现界面不是必需的,TypeScript足够智能拉动来自班级的信息,所以这些也是一样的:

In your case implementing interface is not necessary, TypeScript is smart enough to pull the information from classes too, so these would be the same:

teachers: Teacher[];
teachers: ITeacher[];

如果你有几种类型的教师,你想确保每一个都有意义一个人拥有所有必要的属性/方法:

Creating an interface would make sense if you have several types of teachers, and you wanted to make sure each one has all necessary properties/methods:

class FirstGradeTeacher implements ITeacher{}
class SecondGradeTeacher implements ITeacher{}

您可能已经注意到我根本没有提到JSON。 忘了它! ...使用对象模型(类或接口)时。它只是逻辑模型的数据格式。当您构建模型并规划乳清应该如何工作时,您不关心协议和格式(Http服务处理)。

You may have noticed I've not mention JSON at all. Forget about it! ...when working with your object models (classes or interfaces). It's just a data format for your logical models. When you are structuring your models, and planning how whey should work, you don't care about protocols and formats (Http service handles that).

getTeachers(): Observable<Teacher> {
  return this.http.get('someUrl')
    .map((res: Response) => res.json())
}

此代码是您使用界面的方式。您只需告诉TypeScipt,当您从 someUrl 获得响应并将其解析为 json 时,您希望数据类型为Teacher 。

This code is how you would utilize interface. You just tell TypeScipt that when you get response from someUrl and parse it as json you expect data to be of type Teacher.

然后在其他地方,当你 subscribe()时,它可以告诉你你正在获得的对象有 id 名称学生属性:

Then in other places when you subscribe() to it it can tell you that object you're getting has id, name and students properties:

this._service.getTeachers()
  .subscribe((teachers: Teacher[]) => this.teachers = teachers);

希望这会有所帮助(:

这篇关于HTTP:从JSON对象到Typescript键入断言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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