Angular:错误TS2322:类型'ItemsResponse'不能分配给'string []'

时间:2017-11-29 20:03:51

标签: angular typescript

我的组件不知道该怎么做我收到此错误?

这是组件:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-emails',
  templateUrl: './emails.component.html',
  styleUrls: ['./emails.component.scss']
})

export class EmailsComponent implements OnInit {

test = 'test';
results: string[];

  constructor(private http: HttpClient) { }

  ngOnInit() {

    interface ItemsResponse {
      results: string[];
    }

    this.http.get<ItemsResponse>('assets/api/email_list.json').subscribe(data => {
      this.results = data;
      console.log(this.results);
    });
  }

}

然后我收到这个错误,奇怪的是,即使出现错误也在浏览器中工作?

ERROR in src/app/components/emails/emails.component.ts(24,7): error TS2322: Type 'ItemsResponse' is not assignable to type 'string[]'.
src/app/components/emails/emails.component.ts(24,7): error TS2322: Type 'ItemsResponse' is not assignable to type 'string[]'.
  Property 'includes' is missing in type 'ItemsResponse'.

编辑:添加了json片段:

[
    {
        "pk": "wGR",
        "created": "2017-10-07T01:42:25.110747Z",
        "email_domain": "domain.com",
        "sender_name": null,
        "sender_email": "user@domain.com",
        "has_user_viewed": false,
        "is_shielded": false
    }
]

添加这个,所以我们知道我们在这里和历史原因,所以我在这里学到了新的东西! 当前版本:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-emails',
  templateUrl: './emails.component.html',
  styleUrls: ['./emails.component.scss']
})

export class EmailsComponent implements OnInit {

results: ItemsResponse[]

  constructor(private http: HttpClient) { }

  ngOnInit() {

    interface ItemsResponse {
      pk: string;
      created: string;
      email_domain: string;
      sender_name: string;
      sender_email: string;
      has_user_viewed: boolean;
      is_shielded: boolean;
    }

    this.http.get<ItemsResponse>('assets/api/email_list.json').subscribe(data => {
      this.results = data.results;
      console.log(this.results);
    });
  }

}

2 个答案:

答案 0 :(得分:2)

修改

现在我们有了数据结构:

[
    {
        "pk": "wGR",
        "created": "2017-10-07T01:42:25.110747Z",
        "email_domain": "domain.com",
        "sender_name": null,
        "sender_email": "user@domain.com",
        "has_user_viewed": false,
        "is_shielded": false
    }
]

你应该创建一个这样的界面:

interface ItemsResponse {
  pk: string;
  created: string;
  email_domain: string;
  sender_name: string;
  sender_email: string;
  has_user_viewed: boolean;
  is_shielded: boolean;
}

并将results的定义更改为results: ItemsResponse[]

这意味着this.results将是一个数组,每个元素都是ItemsResponse个对象。

请求完成后,您将能够按预期访问它:

this.results[0]["sender_email"]
this.results[12]["pk"]
this.results.map(item => console.log(item.pk))

等等。

请注意,在我的界面中,我仅使用string作为pk字段,但如果您有一组有限的可能值,例如"wGR", "wGA", "wGP",则可以使用字符串枚举类型像这样:

interface ItemsResponse {
  pk: "wGR" | "wGA" | "wGP";
  // ...
}

要明确解释您遇到错误的原因,您无法将ItemsResponse强制转换为string[],这是您通过将获取请求的响应声明为<ItemsResponse>而执行的操作(这样做会告诉typechecker data将是ItemsResponse),但是你将它分配给this.results,你已声明为string[]。希望上面的插图说明为什么这不会起作用。

原始版本

您有一个类型界面,用于定义名为results字段

interface ItemsResponse {
  results: string[];
}

在您的服务中,您将email_list.json投射到<ItemsResponse>

this.http.get<ItemsResponse>('assets/api/email_list.json').subscribe(data => {
  this.results = data;
  console.log(this.results);
});

这意味着它希望email_list.json看起来像这样:

{
  "results": [
    "one@example.com",
    "two@example.com"
  ]
}

虽然它可能实际上

[
  "one@example.com",
  "two@example.com"
]

所以你需要

  1. 将其指定为this.results = data.results
  2. 将类型界面更改为string[]

答案 1 :(得分:1)

此处:this.http.get<ItemsResponse>您声明http.get的响应数据的类型为ItemsResponse。在此之前,在您的课程中,您声明results是一个字符串数组:results: string[];。但在http的回复中,您将响应分配给this.results。 试试this.results = data.results。 但要确保响应的类型确实是ItemsResponse类型。也许使用console.log