Angular “如何修复错误”;类型';未知[]和#x27;不可分配给类型';产品[]和#x27&引用;
当我在使用最新版本时,遵循Angular 4中的课程,我一辈子都无法解决这个问题。 尝试筛选产品时,Angular “如何修复错误”;类型';未知[]和#x27;不可分配给类型';产品[]和#x27&引用;,angular,typescript,Angular,Typescript,当我在使用最新版本时,遵循Angular 4中的课程,我一辈子都无法解决这个问题。 尝试筛选产品时,products.component.ts中出现错误 任何帮助都将不胜感激,我还是新手,这是我第四天的学习 Type 'unknown[]' is not assignable to type 'Product[]'. Type '{}' is missing the following properties from type 'Product': title, price, category
products.component.ts
中出现错误
任何帮助都将不胜感激,我还是新手,这是我第四天的学习
Type 'unknown[]' is not assignable to type 'Product[]'.
Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl
product.ts
export interface Product {
title: string;
price: number;
category: string;
imageUrl: string;
}
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';
import { Product } from './models/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product) {
return this.db.list('/products').push(product);
}
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
get(productId) {
return this.db.object('/products/' + productId);
}
update(productId, product) {
return this.db.object('/products/' + productId).update(product);
}
delete(productId)
{
return this.db.object('/products/' + productId).remove();
}
}
import { ActivatedRoute } from '@angular/router';
import { CategoryService } from './../category.service';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { Product } from '../models/product';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[];
categories$: Observable<any[]>;
category: string;
filteredProducts: Product[];
constructor(
productService: ProductService,
categoryService: CategoryService,
route : ActivatedRoute) {
productService.getAll().subscribe(a => this.products = a); //error on this.products:
//"Type 'unknown[]' is not assignable to type 'Product[]'."
// "Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl"
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
});
}
}
export interface Product {
key: string;
title: string;
price: number;
category: string;
imageUrl: string;
}
import { ProductService } from './../../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Product } from 'src/app/models/product';
@Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: [ './admin-products.component.css' ]
})
export class AdminProductsComponent implements OnInit, OnDestroy {
products: Product[];
filteredProducts: Product[];
subscription: Subscription;
constructor(private productservice: ProductService) {
this.subscription = this.productservice
.getAll()
.subscribe((products: Product[]) => (this.filteredProducts = this.products = products));
}
filter(query: string) {
this.filteredProducts = query
? this.products.filter((p) => p.title.toLowerCase().includes(query.toLowerCase()))
: this.products;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {}
}
产品.服务.ts
export interface Product {
title: string;
price: number;
category: string;
imageUrl: string;
}
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';
import { Product } from './models/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product) {
return this.db.list('/products').push(product);
}
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
get(productId) {
return this.db.object('/products/' + productId);
}
update(productId, product) {
return this.db.object('/products/' + productId).update(product);
}
delete(productId)
{
return this.db.object('/products/' + productId).remove();
}
}
import { ActivatedRoute } from '@angular/router';
import { CategoryService } from './../category.service';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { Product } from '../models/product';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[];
categories$: Observable<any[]>;
category: string;
filteredProducts: Product[];
constructor(
productService: ProductService,
categoryService: CategoryService,
route : ActivatedRoute) {
productService.getAll().subscribe(a => this.products = a); //error on this.products:
//"Type 'unknown[]' is not assignable to type 'Product[]'."
// "Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl"
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
});
}
}
export interface Product {
key: string;
title: string;
price: number;
category: string;
imageUrl: string;
}
import { ProductService } from './../../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Product } from 'src/app/models/product';
@Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: [ './admin-products.component.css' ]
})
export class AdminProductsComponent implements OnInit, OnDestroy {
products: Product[];
filteredProducts: Product[];
subscription: Subscription;
constructor(private productservice: ProductService) {
this.subscription = this.productservice
.getAll()
.subscribe((products: Product[]) => (this.filteredProducts = this.products = products));
}
filter(query: string) {
this.filteredProducts = query
? this.products.filter((p) => p.title.toLowerCase().includes(query.toLowerCase()))
: this.products;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {}
}
产品.组件.ts
export interface Product {
title: string;
price: number;
category: string;
imageUrl: string;
}
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';
import { Product } from './models/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product) {
return this.db.list('/products').push(product);
}
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
get(productId) {
return this.db.object('/products/' + productId);
}
update(productId, product) {
return this.db.object('/products/' + productId).update(product);
}
delete(productId)
{
return this.db.object('/products/' + productId).remove();
}
}
import { ActivatedRoute } from '@angular/router';
import { CategoryService } from './../category.service';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { Product } from '../models/product';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[];
categories$: Observable<any[]>;
category: string;
filteredProducts: Product[];
constructor(
productService: ProductService,
categoryService: CategoryService,
route : ActivatedRoute) {
productService.getAll().subscribe(a => this.products = a); //error on this.products:
//"Type 'unknown[]' is not assignable to type 'Product[]'."
// "Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl"
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
});
}
}
export interface Product {
key: string;
title: string;
price: number;
category: string;
imageUrl: string;
}
import { ProductService } from './../../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Product } from 'src/app/models/product';
@Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: [ './admin-products.component.css' ]
})
export class AdminProductsComponent implements OnInit, OnDestroy {
products: Product[];
filteredProducts: Product[];
subscription: Subscription;
constructor(private productservice: ProductService) {
this.subscription = this.productservice
.getAll()
.subscribe((products: Product[]) => (this.filteredProducts = this.products = products));
}
filter(query: string) {
this.filteredProducts = query
? this.products.filter((p) => p.title.toLowerCase().includes(query.toLowerCase()))
: this.products;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {}
}
从'@angular/router'导入{ActivatedRoute};
从“/../category.service”导入{CategoryService};
从“/../product.service”导入{ProductService};
从“@angular/core”导入{Component,OnInit};
从“../models/Product”导入{Product};
从“rxjs”导入{Observable};
@组成部分({
选择器:'应用程序产品',
templateUrl:“./products.component.html”,
样式URL:['./products.component.css']
})
导出类产品组件{
产品:产品【】;;
类别:可观察;
类别:字符串;
过滤产品:产品[];
建造师(
productService:productService,
类别服务:类别服务,
路由:ActivatedRoute){
productService.getAll().subscribe(a=>this.products=a);//this.products上的错误:
//“类型“未知[]”不可分配给类型“产品[]”。”
//类型“{}”缺少类型“产品”中的以下属性:标题、价格、类别、imageUrl
this.categories$=categoryService.getAll();
route.queryParamMap.subscribe(参数=>{
this.category=params.get('category');
this.filteredProducts=(this.category)?
this.products.filter(p=>p.category===this.category):this.products;
});
}
}
我认为这是因为您没有指定使用getAll()方法检索的数据类型
TypeScript是一种强类型语言,因此它试图在编译时验证所有类型和赋值
尝试使用以下命令更改不稳定的线:
productService.getAll().subscribe((a: Product[]) => this.products = a);
问题在于这个可观察到的-
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
您正在将操作数组映射到一个数组。
当您需要一个数组(即产品[])时
因此,请确保将操作数组映射到产品数组(即数组)
尝试像这样更改代码-
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => {
title: <fill this from equivalent in a>,
price: <fill this from equivalent in a>,
category: <fill this from equivalent in a>,
imageUrl: <fill this from equivalent in a>
})
)
);
}
getAll(){
返回此.db.list(“/products”).snapshotChanges()
.烟斗(
映射(操作=>
actions.map(a=>{
标题:,
价格:,
类别:,
图像URL:
})
)
);
}
顺便说一句,问题不在角度4和角度8之间[同样的例子也会给出角度8相同的错误]。这就是Typescript类型检查的工作原理。如果您使用普通javascript编写相同的代码,那么您可能在编译时没有看到任何错误,但在运行时会看到意外的行为。这里,typescript确保在编译时尽可能多地捕获错误。product.ts
export interface Product {
title: string;
price: number;
category: string;
imageUrl: string;
}
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';
import { Product } from './models/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product) {
return this.db.list('/products').push(product);
}
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
get(productId) {
return this.db.object('/products/' + productId);
}
update(productId, product) {
return this.db.object('/products/' + productId).update(product);
}
delete(productId)
{
return this.db.object('/products/' + productId).remove();
}
}
import { ActivatedRoute } from '@angular/router';
import { CategoryService } from './../category.service';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { Product } from '../models/product';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[];
categories$: Observable<any[]>;
category: string;
filteredProducts: Product[];
constructor(
productService: ProductService,
categoryService: CategoryService,
route : ActivatedRoute) {
productService.getAll().subscribe(a => this.products = a); //error on this.products:
//"Type 'unknown[]' is not assignable to type 'Product[]'."
// "Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl"
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
});
}
}
export interface Product {
key: string;
title: string;
price: number;
category: string;
imageUrl: string;
}
import { ProductService } from './../../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Product } from 'src/app/models/product';
@Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: [ './admin-products.component.css' ]
})
export class AdminProductsComponent implements OnInit, OnDestroy {
products: Product[];
filteredProducts: Product[];
subscription: Subscription;
constructor(private productservice: ProductService) {
this.subscription = this.productservice
.getAll()
.subscribe((products: Product[]) => (this.filteredProducts = this.products = products));
}
filter(query: string) {
this.filteredProducts = query
? this.products.filter((p) => p.title.toLowerCase().includes(query.toLowerCase()))
: this.products;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {}
}
产品.组件.ts
export interface Product {
title: string;
price: number;
category: string;
imageUrl: string;
}
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';
import { Product } from './models/product';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private db: AngularFireDatabase) { }
create(product) {
return this.db.list('/products').push(product);
}
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
get(productId) {
return this.db.object('/products/' + productId);
}
update(productId, product) {
return this.db.object('/products/' + productId).update(product);
}
delete(productId)
{
return this.db.object('/products/' + productId).remove();
}
}
import { ActivatedRoute } from '@angular/router';
import { CategoryService } from './../category.service';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { Product } from '../models/product';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[];
categories$: Observable<any[]>;
category: string;
filteredProducts: Product[];
constructor(
productService: ProductService,
categoryService: CategoryService,
route : ActivatedRoute) {
productService.getAll().subscribe(a => this.products = a); //error on this.products:
//"Type 'unknown[]' is not assignable to type 'Product[]'."
// "Type '{}' is missing the following properties from type 'Product': title, price, category, imageUrl"
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
});
}
}
export interface Product {
key: string;
title: string;
price: number;
category: string;
imageUrl: string;
}
import { ProductService } from './../../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Product } from 'src/app/models/product';
@Component({
selector: 'app-admin-products',
templateUrl: './admin-products.component.html',
styleUrls: [ './admin-products.component.css' ]
})
export class AdminProductsComponent implements OnInit, OnDestroy {
products: Product[];
filteredProducts: Product[];
subscription: Subscription;
constructor(private productservice: ProductService) {
this.subscription = this.productservice
.getAll()
.subscribe((products: Product[]) => (this.filteredProducts = this.products = products));
}
filter(query: string) {
this.filteredProducts = query
? this.products.filter((p) => p.title.toLowerCase().includes(query.toLowerCase()))
: this.products;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {}
}
products.component.html
<tr *ngFor="let p of filteredProducts">
<td>{{ p.title }}</td>
<td>{{ p.price }}</td>
<td>
<a [routerLink]="['/admin/admin-products/', p.key]">Edit</a>
</td>
</tr>
{{p.title}}
{{p.price}}
编辑
AFAIK列表
是通用的,您可以也应该提供键入。而不是
return this.db.list('/products').snapshotChanges()
做
返回此.db.list('/products').snapshotChanges()
这会改变你的生活
getAll() {
return this.db.list<Product>('/products').snapshotChanges()
.pipe(
map(actions =>
actions.map(a => ({ key: a.key, ...a.payload.val() }))
)
);
}
getAll(){
返回此.db.list(“/products”).snapshotChanges()
.烟斗(
映射(操作=>
actions.map(a=>({key:a.key,…a.payload.val()}))
)
);
}
谢谢您的回答,但这不起作用。我想我会放弃这门课,去寻找能教我英语的东西,而不是4。除此之外,我还得花几个小时阅读文档和stackoverflow来解决一些小问题:如果你能在回答中添加一些描述,那就太好了。你能解释一下解决方案吗?它有什么作用?与问题中的代码相比,它有什么不同?