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

时间:2019-11-01 16:04:30

标签: angular typescript

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

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

这是user.ts代码。

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对象。 我的组件代码:

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

2 个答案:

答案 0 :(得分:1)

  

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

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

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

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

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

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

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

还请阅读 classes interfaces

上的文档

答案 1 :(得分:0)

您不能限制服务器响应。 试试这个:

服务:

getUser(id: string): User {
    const user = this._httpClient.get(this._url + '/' + id);
    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
        }
    };
}

说明: const user是从jsonplaceholder返回的整个对象。 return可以将响应转换为您的需求。

您应该将UserAddress定义为接口而不是类。

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

export interface User {
   id: number;
   name: string;
   phone: string;
   email: string; 
   address: Address;
}