【问题标题】:Typescript type safety - service doesn't return specified class object打字稿类型安全 - 服务不返回指定的类对象
【发布时间】:2020-02-27 22:25:06
【问题描述】:

很简单的问题。 这是服务代码:

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 方法按我的预期返回用户的 Observable。
我想像这样在组件中获取用户对象:
{ 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 代码中获取用户对象。 我的组件代码:

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

【问题讨论】:

  • console.log(user) 打印什么?

标签: angular typescript


【解决方案1】:

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

服务:

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 会根据您的需求转换响应。

您应该将User 和Address 定义为接口而不是类。

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

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

【讨论】:

    【解决方案2】:

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

    ...您误解了这意味着什么。您当前在代码中所说的只是告诉编译器您期望您的 http-request 将返回的内容将符合您创建的模型。对此没有运行时检查。这只是在您编写代码时为您提供帮助,因为编译器可以告诉您何时您正在执行不符合您的模型的操作。这将使您的调试更容易。

    所以你需要手动设置你想要的属性。通过编写一个为您执行此操作的函数,或者像我在这里所做的那样,在map 中。此外,与其他答案一样,如果没有特定于类的方法,我会使用接口。

    如前所述,您需要设置所需的属性。这里我比较懒,使用any作为http-request的返回类型,因为你不能使用User,因为这不是你从http-request得到的。您将转换响应以返回 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

    上的文档

    【讨论】:

      猜你喜欢
      • 2022-10-01
      • 2015-11-06
      • 2019-09-01
      • 2021-08-15
      • 2020-04-28
      • 1970-01-01
      • 2021-12-30
      • 2020-06-29
      • 1970-01-01
      相关资源
      最近更新 更多