Typescript类型安全-服务不会返回指定的类对象 [英] Typescript type safety - service doesn't return specified class object

查看:72
本文介绍了Typescript类型安全-服务不会返回指定的类对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

非常简单的问题.服务代码如下:

Very simple question. Here is the service code:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from './user';

@Injectable()
export class UserService {
   private _url = "https://jsonplaceholder.typicode.com/users";

   constructor(private _httpClient: HttpClient) {
   }

   getUser(id: string){
      return this._httpClient.get<User>(this._url + '/' + id);
   }
}

getUser方法按预期返回User的Observable.
我想在这样的组件中获取User对象:
{id:1,名称:"a",电话:"b",电子邮件:"c",地址:{街道:"d",套房:"e",城市:"f",邮政编码:"g"}}

getUser method returns Observable of User as I expect.
I want to get User object in component like this:
{ id: 1, name: "a", phone: "b", email: "c", address: {street: "d", suite: "e", city: "f", zipcode: "g"} }

这是user.ts代码.

Here is the user.ts code.

export class Address {
   street: string;
   suite: string;
   city: string;
   zipcode: string;    
}

export class User {
   id: number;
   name: string;
   phone: string;
   email: string; 
   address = new Address();
}

当我从组件调用服务时,我从jsonplaceholder获得整个用户对象,而不是从我的user.ts代码获得User对象.我的组件代码:

When I call the service from component I get the whole user object from jsonplaceholder, not the User object from my user.ts code. My component code:

import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
   selector: 'newuserform',
   templateUrl: './newuser-form.component.html',
   providers: [UserService]
})
export class NewUserFormComponent implements OnInit {
constructor(
   private _service: UserService, 
   private _router: Router,
   private _route: ActivatedRoute) { }

 ngOnInit(){
    let id = this._route.snapshot.paramMap.get('id');
    this._service.getUser(id)
       .subscribe(
          user => console.log(user);
       );
 }
 }

推荐答案

Typescript类型安全-服务不会返回指定的类对象

Typescript type safety - service doesn't return specified class object

...您误解了这是什么意思.您当前在代码中告诉的内容只是告诉编译器您期望http请求返回的内容将符合您创建的模型.对此没有运行时检查.这只是在编写代码时为您提供帮助,因为编译器会在执行不符合模型的操作时告诉您.它将使您的调试更加容易.

... you have misunderstood what that means. What you are currently telling in your code, is only telling the compiler that what you expect that your http-request will return will conform to the model you have created. There is no runtime check for this. This is only to help you when you are writing code, since the compiler can tell you when you are doing something that doesn't conform to your models. It will make your debugging easier.

因此,您实际上需要手动设置所需的属性.可以通过在 map 内编写为您执行此操作的函数,或者像我在此处所做的那样.另外,像其他答案一样,如果没有特定于类的方法,我将使用接口.

So you need to actually manually set the properties you want. Either by writing a function that does that for you, or like I do here, inside map. Also, like in other answer, I would use interfaces if there are no class specific methods.

如前所述,您需要设置所需的属性.在这里我很懒,并且使用 any 作为http-request的返回类型,因为您不能使用 User ,因为那不是您从http-request中获得的.您将通过以下方式转换响应以返回 User :

As said, you need to set the properties you want. Here I am lazy and use any as the return type of the http-request, since you cannot use User, since that is not what you get from the http-request. You will transform the response to return a User though:

  getUser(id: string): Observable<User> {
    return this._httpClient.get<any>(this._url + "/" + id).pipe(
      map((user: any) => {
        return {
          id: user.id,
          name: user.name,
          phone: user.phone,
          email: user.email,
          address: {
            street: user.address.street,
            suite: user.address.suite,
            city: user.address.city,
            zipcode: user.address.zipcode
          } as Address
        } as User
      })
    );
  }
}

在这种情况下,您还可以删除不需要的属性:

In this case you could also delete the properties that you don't want:

getUser(id: string): Observable<User> {
  return this._httpClient.get<any>(this._url + "/" + id).pipe(
    map((user: any) => {
      delete user.company;
      delete user.address.geo;
      delete user.website;
      return user as User;
    })
  );
}

STACKBLITZ 这两个选项.

STACKBLITZ for both options.

还请阅读有关 的文档和 界面

Also read the documentation on classes and interfaces

这篇关于Typescript类型安全-服务不会返回指定的类对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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