简体   繁体   English

与promise一起使用时的角度更改接口定义

[英]Angular change Interface definition when I use as with promise

I have predefined properties in interface as below: 我在界面中具有预定义的属性,如下所示:

export interface User {
  userID : number;
  userName : string;
  userAge : string;
}

Also, I have service which returns some dummy data from some dummy REST api. 另外,我有从一些虚拟REST API返回一些虚拟数据的服务。

getUsers(){
    return this.http.get("https://fakerestapi.azurewebsites.net/api/Authors").toPromise();
  }

and in component I am consuming this service and convert data to userlist as per below code: 在组件中,我正在使用此服务,并按照以下代码将数据转换为用户列表:

 _service.getUsers().then(i => { this.userList = i as User[]; console.log(this.userList) });

as you can see, I used 'AS' to convert response to my respective user[] array. 如您所见,我使用“ AS”将响应转换为各自的user []数组。

ISSUE: 问题:
dummy REST api retruns following data 虚拟REST api重新运行以下数据

{
    "ID": 1,
    "IDBook": 1,
    "FirstName": "First Name 1",
    "LastName": "Last Name 1"
  }

and user class doesn't have property of ID, IDBook etc. still when I check console, it automatically change the definition of User class and shows all the data although properties are not matched. 并且用户类不具有ID,IDBook等属性。当我检查控制台时,它会自动更改User类的定义并显示所有数据,尽管属性不匹配。

Link: https://stackblitz.com/edit/angular-pryy3f?file=src%2Fapp%2Fappservice.service.ts 链接: https//stackblitz.com/edit/angular-pryy3f?file = src%2Fapp%2Fappservice.service.ts

As per my understanding only match properties should be displayed not all. 根据我的理解,仅显示匹配属性,而不是全部。

In typescript as keyword is not a type casting but a type assertion. 在typescript中as关键字不是类型转换,而是类型声明。 So what is happening is this: 所以这是怎么回事:

  • you ask for a User[] 您要求一个User[]
  • you receive a JSON object[] 您收到一个JSON object[]
  • the JSON object[] is transformed into a User's interface array (look at what is an interface in typescript) JSON object[]转换为用户的接口数组(看看打字稿中的接口是什么)
  • the compiler accept this.userList as a User[] but it is only a type assertion 编译器将this.userList作为User[]接受,但这只是类型断言

So using as keyword is redundant in this case and completely useless. 因此as在这种情况下,使用as关键字是多余的,并且完全没有用。

A type assertion is only useful for autocompletion and other similar things that are elaborated at compile time. 类型断言仅对自动完成和在编译时详细说明的其他类似事情有用。 But it is not a real cast. 但这不是真正的演员。 So when you execute your code this.userList is always a JSON Object[] 因此,当您执行代码时, this.userList始终是JSON Object[]

If you need real User objects you should do something like this: 如果需要真正的用户对象,则应执行以下操作:

_service.getUsers().then(i => { 
    this.userList = i.map(u => new User(u)); 
    console.log(this.userList) 
});

Obviously you should define a constructor into your User class 显然,您应该在User类中定义一个构造函数

EDIT 编辑

Looking at your Authors file I can see you are using an xml syntax that is converted into an array treated as Object. 查看您的Authors文件,我可以看到您正在使用xml语法,该语法已转换为被视为Object的数组。 For this reason map operator fails. 因此,映射运算符失败。 I have changed a bit your code 我更改了您的代码

User 用户

export class User {
  userID : number;
  FirstName : string;
  userAge : string;

  constructor()
  constructor(u: User)
  constructor(u?: User) {
     this.userID = u && u.userID || -1;
     this.FirstName = u && u.FirstName || '';
     this.userAge = u && u.userAge || '';
  }

  clone(): User {
    // TODO CLONE USER
    return new User();
  }
}

AppComponent AppComponent

import { Component } from '@angular/core';
import { AppserviceService } from './appservice.service';
import { User } from './user';
import 'rxjs/add/operator/map';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private userList: User[] = [];
  constructor(private _service: AppserviceService) {
    _service.getUsers().then(i => {  
      for (let c=0; c<10; c++) {
        let u = new User(i[c]);
        this.userList.push(u);
      }

      console.log('this.userList', this.userList);
    });
  }
}

Defining an interface with Typescript has absolutely no effect on generated Javascript code, since interfaces do not exist in Javascript. 用Typescript定义接口对生成的Javascript代码绝对没有影响,因为Javascript中不存在接口。 You can figure it out by playing with the Typescript playground . 您可以通过在Typescript游乐场玩耍弄清楚 Interfaces are just something that help you (as a developer) and your team detecting errors at compilation time. 接口只是可以帮助您(作为开发人员)和您的团队在编译时检测错误的东西。

So the object you return from HTTP will always be as is, regardless of the interface you apply to it, because there is no such thing as interface or cast in Javascript. 因此,从HTTP返回的对象将始终保持原样,而与您对其应用的接口无关,因为在Javascript中没有接口或强制转换这样的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM