[英]angular Property 'value' does not exist on type 'Object'
在我的 Angular 应用程序中,我对 API 调用的响应存在问题:
private async getActor(actor:string) {
const response = await this.searchActor.getActorImage(actor).toPromise()
let actPics = []
for (var val of (response as any[]).value) {
actPics.push(val.thumbnailUrl)}
}
我的应用程序运行良好,但是当我运行ng serve
时,控制台中有此消息
错误:src/app/quiz-editor/actor-question/actor-question.component.ts:55:41 - 错误 TS2551:“任何 []”类型上不存在属性“值”。 您指的是 'values' 吗?
55 for (var val of (response as any[]).value) { ~~~~~
node_modules/typescript/lib/lib.es2015.iterable.d.ts:75:5 75 个值():IterableIterator; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 这里声明了“值”。
当我console.log(response)
我得到:
我做了一些研究,我读到我应该声明response
,但我应该怎么做呢?
我试过这个解决方案:
private async getActor(actor:string) {
const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
let actPics = []
for (let val of response.value) {
actPics.push(val.thumbnailUrl)}
}
但现在我有这个错误:
Error: src/app/quiz-editor/actor-question/actor-question.component.ts:55:11 - error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
Property 'value' is missing in type 'Object' but required in type '{ value: any[]; }'.
55 const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
~~~~~~~~
src/app/quiz-editor/actor-question/actor-question.component.ts:55:23
55 const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
~~~~~
'value' is declared here.
正如您的日志语句所示,您的response
是一个包含value
作为键的 object。 因此,您可以执行以下操作:
const response: { value: any[] } = await this.searchActor.getActorImage(actor).toPromise();
let actPics = [];
for (let val of response.value) {
actPics.push(val.thumbnailUrl);
}
您必须告诉 typescript 您的阵列是什么类型。 通过说response as any[]
编译器不知道您的数组包含哪些对象。 它可能在运行时工作,因为 typescript 然后“找到”请求的属性。 所以你应该做的是创建一个类/接口来定义你希望从你的 API 接收到的 object,然后解析对它的响应。
例子:
private async getActor(actor:string) {
const response = await this.searchActor.getActorImage(actor).toPromise();
const images = response as actorImage[];
let actPics = [];
for (var val of images) {
actPics.push(val.thumbnailUrl)}
}
interface actorImage{
thumbnailUrl: string
}
您将response
声明为any
类型的数组,这是不正确的。 response
不是数组, response.value
是数组。 any
关键字告诉 typescript 不要打扰类型检查。 从文档:
在某些情况下,并非所有类型信息都可用,或者它的声明会花费不适当的努力。 这些可能发生在没有 TypeScript 或第 3 方库的情况下编写的代码中的值。 在这些情况下,我们可能希望选择退出类型检查。 为此,我们将 label 这些值与任何类型
因此,快速而肮脏的解决方法是告诉 typescript response
类型为any
,执行如下操作:
private async getActor(actor:string) {
const response = await this.searchActor.getActorImage(actor).toPromise()
let actPics = []
for (var val of (response as any).value) {
actPics.push(val.thumbnailUrl)}
}
另一种可能更适合 Angular 的做事方式是创建 model 并将其用作您的类型。 这是一个精简的 model:
export class ImageSearchResult {
// you could/should type this as well instead of being an array of
// type any. It might be something like value: []ImageData;
value: []any;
}
然后,您使用 model 类型而不是任何类型:
private async getActor(actor:string) {
const response = await this.searchActor.getActorImage(actor).toPromise()
let actPics = []
for (var val of (response as ImageSearchResult).value) {
actPics.push(val.thumbnailUrl)}
}
但更进一步,您的服务应该返回正确的类型。 输入服务返回的数据不是使用服务的模块的工作。 另外-我假设您要返回一个observable
。 为什么调用toPromise
? 让我们创建一个服务 function,它使用 Angular 的 http 服务并返回一个正确类型的 observable。 你可能已经有了这样的东西:
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) { }
/**
* Search for images by actor. Returns an observable of type ImageSearchResult.
* @param actor The name of the actor you want to search
*/
getActorImage(actor: string): Observable<ImageSearchResult> {
// Refactor to appropriate http action type (post/push/etc) and url.
return this.http.get<ImageSearchResult>(`https://my-api.com/actor-search?q=${actor}`);
}
然后消费这个服务function:
private getActor(actor:string) {
this.searchActor.getActorImage(actor).subscribe(response => {
let actPics = []
// No casing necessary, response is already correct type.
for (var val of response.value) {
actPics.push(val.thumbnailUrl)
}
});
}
最后,看起来您可能正在尝试使用 Azure 图像搜索 API。 在这种情况下,看看他们如何键入返回对象以获得灵感。 根据您项目的许可证,您可能只需导入该项目并将其模型与您的服务一起使用。
您错误地尝试将response
定义为数组。 Javascript Array
显然没有value
属性或方法。 您需要改为定义以下接口。
export interface IResponse {
currentOffset: number;
instrumentation: any;
nextOffset: number;
queryContext: any;
readLink: string;
totalEstimatedMatches: any;
value: Array<any>;
webSearchUrl: string;
_type: string;
}
在理想情况下,您还将为instrumentation
、 queryContext
和totalEstimatedMatches
以及包含在value
数组中的 object 定义类似的接口,并使用它们而不是使用any
。
此外,您不需要显式循环来从 object 获取值数组。 您可以改用Array#map
方法。
export interface IResponse {
currentOffset: number;
instrumentation: any;
nextOffset: number;
queryContext: any;
readLink: string;
totalEstimatedMatches: any;
value: Array<any>;
webSearchUrl: string;
_type: string;
}
@Component({...})
export class SomeComponent implements OnInit, OnDestroy {
private async getActor(actor:string) {
const response: IResponse = await this.searchActor.getActorImage(actor).toPromise();
let actPics: Array<string> = response.value.map(val => val['thumbnailUrl']);
}
}
补充说明:
该错误是由于您将响应投射到“any []”而引起的。 => 你有 2 个解决方案:
您删除铸件(没有必要):
private async getActor(actor:string) { const {value} = await this.searchActor.getActorImage(actor).toPromise() const actPics = value.map(val => val.thumbnailUrl)
}
您声明一个接口,表示您的 API 响应的类型
你只需要改变类型
const response:{value:any[]}
或者
const response:any
两者都可以
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.