“对象”类型上不存在属性“”。可观察订阅

Posted

技术标签:

【中文标题】“对象”类型上不存在属性“”。可观察订阅【英文标题】:Property '' does not exist on type 'Object'. Observable subscribe 【发布时间】:2017-02-27 02:41:30 【问题描述】:

我刚开始使用 Angular2,遇到了一个我无法真正理解的问题。

我有一些这样创建的模拟数据:

export const WORKFLOW_DATA: Object =

    "testDataArray" : [
         key: "1",              name: "Don Meow",   source: "cat1.png" ,
         key: "2", parent: "1", name: "Roquefort",    source: "cat2.png" ,
         key: "3", parent: "1", name: "Toulouse",   source: "cat3.png" ,
         key: "4", parent: "3", name: "Peppo", source: "cat4.png" ,
         key: "5", parent: "3", name: "Alonzo",     source: "cat5.png" ,
         key: "6", parent: "2", name: "Berlioz", source: "cat6.png" 
    ]
;

然后将其导入服务并“观察”

import  Injectable  from '@angular/core';

import  WORKFLOW_DATA  from './../mock-data/workflow'
import Observable from "rxjs";

@Injectable()
export class ApiService 

  constructor()  

  getWorkflowForEditor(): Observable<Object>
  
      return Observable.of( WORKFLOW_DATA );
  


然后我有一个组件,在构造函数中:

constructor( private apiService: ApiService)
    
        this.apiService.getWorkflowForEditor().subscribe( WORKFLOW_DATA => 
            console.log( WORKFLOW_DATA);
            console.log( WORKFLOW_DATA.testDataArray );
         );
    

第一个 console.log 记录一个 Object 类型的 Object,其中包含 testDataArray 属性。

第二个console.log,编译时出错:

Property 'testDataArray' does not exist on type 'Object'.

同时仍按预期记录对象数组 [Object, Object, ..]。

我真的不明白为什么,我确定我做错了什么,我想要一个解释。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

如果您的方法是Observable&lt;Object&gt;,则返回类型。因此,当您订阅时,这将是传递的类型。 Object 类型上没有 testDataArray。你可以做几件事:

    键入数据和返回类型不同

    WORKFLOW_DATA:  testDataArray: any  = []
    
    getWorkflowForEditor(): Observable< testDataArray: any >
    

    或者只是键入断言响应数据到any

    console.log( (<any>WORKFLOW_DATA).testDataArray );
    

【讨论】:

【参考方案2】:

当你告诉打字稿时:

WORKFLOW_DATA: Object

你告诉它WORKFLOW_DATA 是一个没有属性的普通对象。当您稍后尝试访问 WORKFLOW_DATA.testDataArray 时,编译器会认为您滥用了该类型。

如果您想对WORKFLOW_DATA 进行类型检查,您需要创建一个描述您的对象的接口。

【讨论】:

如您所见,其他答案建议使用 any,我个人觉得使用接口是正确的方法,尽管对于像这样简单的事情有点冗长。接口是 Angular2 的最佳实践吗? 类型系统可以帮助您,尤其是随着应用程序的增长。如果您不想使用,则不需要使用其中的任何一个——它对最终的 javascript 没有影响。我(我认为大多数其他人)喜欢它,因为智能编辑器提供自动完成功能并警告您犯错。如果这是我的代码,我可能会为记录创建一个类型 - key: string, parent?:string ..,为包含记录类型的集合创建一个类型 - testDataArray: recordType[]... 或类似的东西。【参考方案3】:

Typescript 预计 WORKFLOW_DATA 在此处为 Object

.subscribe( WORKFLOW_DATA =>  )

因为你是这么说的:

  getWorkflowForEditor(): Observable<Object>

但是 Object 没有 testDataArray 属性...你应该告诉 TypeScript 数据可以有任何属性:

  getWorkflowForEditor(): Observable<any>

或使用

console.log( WORKFLOW_DATA["testDataArray"] );

【讨论】:

【参考方案4】:

添加 Observable

在您订阅的 service.ts 方法中。在 Observable 上,您可以引用类型对象或提及以接受所有类型的条目

getResponse(query: string): Observable<any> 
    let data = 
      query: query,
      lang: "en",
      sessionId: "1234567",
    ;
    return this.http.post(this.baseURL, data);
  

【讨论】:

以上是关于“对象”类型上不存在属性“”。可观察订阅的主要内容,如果未能解决你的问题,请参考以下文章

“员工”类型上不存在属性“forEach”

从服务订阅数据时,类型 void 上不存在错误属性订阅?

可观察类型上不存在 fromPromise

Angular 2:“Observable<Response>”类型上不存在属性“toPromise”

“对象”类型上不存在属性“成功”

Angular 4 属性在构建时类型对象上不存在