Angular 理解通过映射将类型强制转换到接口中

Angular 理解通过映射将类型强制转换到接口中,angular,typescript,observable,Angular,Typescript,Observable,我是angular方面的新手,我试图理解从响应到接口的映射是如何工作的 我有以下回应: [ { "id": 2, "name" : "Josh", } ]; 我的TS界面如下所示: export interface User { name: string; id: number | null; } return this.http.get<User>('h

我是angular方面的新手,我试图理解从响应到接口的映射是如何工作的

我有以下回应:

   [ {
   "id": 2,
   "name" : "Josh",
    } ];
我的TS界面如下所示:

   export interface User {
      name: string;
      id: number | null;
     }
return this.http.get<User>('http://localhost:4200/user/1').pipe(
  map((response: User) =>
      if(response.id && response.name)
          this.response = response;
      else
          console.log('This is not a user!');
  ));
}
我在服务中拨打了一个简单的get电话:

   getUser() {
   return this.http.get<User>('http://localhost:4200/user/1').pipe(
          map((response: User) =>
          this.response = response,
          ));
      }
我的用户也是来自类型用户:

   user: User;
我期望得到的是user类型的user属性。如果响应中的属性与用户界面中的属性不匹配(例如,我传递了一个“id2”属性),则我还希望出现错误,请参见下面的图片

这种情况下,只需在TS中定义一个用户实例:


我的问题是,为什么映射在属性不匹配的情况下仍然有效?难道我不应该出错吗?如果是这样的话,有没有办法获取错误?

您必须记住,Typescript将在执行之前编译成Javascript。 Javascript没有类型检查,所以当您编写

getUser() {
   return this.http.get<User>('http://localhost:4200/user/1').pipe(
   map((response: User) =>
          this.response = response,
   ));
}
getUser(){
返回此.http.get('http://localhost:4200/user/1)。烟斗(
映射((响应:用户)=>
this.response=响应,
));
}
您的意思是您确信http请求将返回一个与用户具有相同结构的对象。 问题是在运行时(当调用实际执行时),不会进行类型检查,因为浏览器正在读取Javascript,而不是Typescript。 检查对象一致性的唯一方法是检查对象是否具有所有属性。 所以,如果用户有id和名称,您可以如下更改地图:

   export interface User {
      name: string;
      id: number | null;
     }
return this.http.get<User>('http://localhost:4200/user/1').pipe(
  map((response: User) =>
      if(response.id && response.name)
          this.response = response;
      else
          console.log('This is not a user!');
  ));
}
返回此.http.get('http://localhost:4200/user/1)。烟斗(
映射((响应:用户)=>
if(response.id&&response.name)
这个。反应=反应;
其他的
log('这不是用户!');
));
}

您必须记住,Typescript将在执行之前编译成Javascript。 Javascript没有类型检查,所以当您编写

getUser() {
   return this.http.get<User>('http://localhost:4200/user/1').pipe(
   map((response: User) =>
          this.response = response,
   ));
}
getUser(){
返回此.http.get('http://localhost:4200/user/1)。烟斗(
映射((响应:用户)=>
this.response=响应,
));
}
您的意思是您确信http请求将返回一个与用户具有相同结构的对象。 问题是在运行时(当调用实际执行时),不会进行类型检查,因为浏览器正在读取Javascript,而不是Typescript。 检查对象一致性的唯一方法是检查对象是否具有所有属性。 所以,如果用户有id和名称,您可以如下更改地图:

   export interface User {
      name: string;
      id: number | null;
     }
return this.http.get<User>('http://localhost:4200/user/1').pipe(
  map((response: User) =>
      if(response.id && response.name)
          this.response = response;
      else
          console.log('This is not a user!');
  ));
}
返回此.http.get('http://localhost:4200/user/1)。烟斗(
映射((响应:用户)=>
if(response.id&&response.name)
这个。反应=反应;
其他的
log('这不是用户!');
));
}

没有错误是什么意思?您发布的屏幕截图中有错误…显然编译器不会提出错误,因为您的代码是好的。在运行时,如果服务器返回的对象与预期接口不匹配,则它将映射任何匹配的属性并以静默方式继续,除非代码预期属性为非null且服务器不返回此属性。您需要验证代码中的响应形状并防止错误响应。您已经有错误。。。只能对匹配字段进行映射。。。你已经有一个错误,所以你可以看到类型检查工作。。。在类中指定字段i2以将其删除。别忘了,在运行时interace不再存在。@dani_bandita(希望我理解您想要实现的目标)我的意思是,如果您希望服务器返回对象
{id:string;name:string;}
,您应该检查例如
if(response.id==未定义){error handing code}
。这将处理服务器发回的场景,例如
{id2:string;name:string;}
。顺便说一句,通过“shape”我指的是对象结构。你说没有错误是什么意思?你发布的屏幕截图中有错误…显然,编译器不会引发错误,因为你的代码是好的。在运行时,如果服务器返回一个与预期接口不匹配的对象,那么它将映射任何匹配的属性,并静默地继续,除非你的代码是正确的将属性预期为非null,而服务器不返回此属性。您需要验证代码中的响应形状并防止错误响应。您已经有错误…只能对匹配的字段进行映射…您已经有错误,以便可以看到类型检查工作…在类中指定要删除的字段i2别忘了,interace在运行时已经不存在了。@dani_bandita(希望我能理解你想要实现什么)我的意思是,例如,如果你希望服务器返回一个对象
{id:string;name:string;}
,你应该检查
如果(response.id==未定义){error handing code}
。这将处理服务器发回的场景,例如,
{id2:string;name:string;}
。顺便说一句,通过“shape”我指的是对象结构。没错。正如我在上面对问题的评论。谢谢@Federico Galfione和@Benny!我知道TS/JS的区别,但不知道浏览器没有进行任何类型检查。没错。正如我在上面对问题的评论。谢谢@Federico Galfione和@Benny!我知道TS/JS的区别,但没有请注意,浏览器不执行任何类型检查。