键入'键:字符串; ' 不可分配给类型 'Product' Angular 7

Posted

技术标签:

【中文标题】键入\'键:字符串; \' 不可分配给类型 \'Product\' Angular 7【英文标题】:Type ' key: string; ' is not assignable to type 'Product' Angular 7键入'键:字符串; ' 不可分配给类型 'Product' Angular 7 【发布时间】:2019-07-01 13:59:39 【问题描述】:

我遇到了这个问题“类型 ' key: string; ' 不能分配给类型 'Product'。”当我将 Product 接口类型添加到数组 products 变量时。

这是我的代码:

product.ts

export interface Product 
    title: string;
    price: number;
    category: string;
    imageUrl: string;

productService.ts

import  Injectable  from '@angular/core';
import  AngularFireDatabase  from 'angularfire2/database';
import  map  from 'rxjs/operators';

@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).valueChanges();
  

  update(productId, product)
    return this.db.object('/products/' + productId).update(product);
  

  delete(productId)
    return this.db.object('/products/' + productId).remove();
  

admin-product.component.ts

import  Component, OnInit, OnDestroy  from '@angular/core';
import  ProductService  from 'src/app/product.service';
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: any[];
  subscription: Subscription;
  dataSource;
  displayedColumns: string[] = ['title', 'price', 'action'];

  constructor(private productService: ProductService)
    this.subscription = this.productService.getAll().subscribe(products => this.filteredProducts = this.products = products);
  

  ngOnInit()  

  filter(query: string)
    if(query)
      this.filteredProducts = this.products.filter(p => p.title.toLowerCase().includes(query.toLowerCase()));
    else
      this.filteredProducts = this.products;
    
  

  ngOnDestroy()
    this.subscription.unsubscribe();
  

终端错误

ERROR in src/app/admin/admin-products/admin-products.component.ts(19,100): error TS2322: Type ' key: string; []' is not assignable to type 'Product[]'.

src/app/admin/admin-products/admin-products.component.ts(19,100): error TS2322: Type ' key: string; []' 不可分配给类型 'Product[]'。 键入'键:字符串; ' 不可分配给类型“产品”。 类型 ' key: string; 中缺少属性 'title' '。

谁能帮帮我?

【问题讨论】:

this.db.list('/products').snapshotChanges()返回的observable中有哪些类型? 【参考方案1】:

只是一个建议,

您似乎已将某些内容映射并分配给提到的名称(键)。

getAll()
    return this.db.list('/products').snapshotChanges()
      .pipe(
        map(actions =>
          actions.map(a => ( key: a.key, ...a.payload.val() )) //here you have made something strange.
        )
      );
  

解决方案:- 您需要映射正确的接口模型变量。

example,
  .map( title: a.something;
    price: a.something;
    category: a.something;
    imageUrl: a.something
)

【讨论】:

感谢您的重播@Karnan Muthukumar。在您的帮助下,我使用此代码使其工作: getAll() return this.db.list('/products').snapshotChanges() .pipe( map(actions => actions.map(a => ( key: a.key, ...a.payload.val() as Product)) ) ); 【参考方案2】:

感谢大家重播。

在您 Karnan Muthukumar 的帮助下,我使用此代码开始工作:

getAll()
    return this.db.list('/products').snapshotChanges()
      .pipe(
        map(actions =>
          actions.map(a => ( key: a.key, ...a.payload.val()  as Product))
        )
      );
  

【讨论】:

key 如果您以后想使用它,产品界面上仍然不可用。您可以将其添加到允许其他地方使用该属性的界面。这样,您就不必将类型转换为 Product,它会正常工作。 对界面的添加键仍然需要“作为产品”来节省一天的清洁和简单!【参考方案3】:

您可以 console.log 记录 this.db.list('/products').snapshotChanges() 返回的 observable 并查看上面的参数,可能还有更多的东西,只有 Product 所以您必须从这个 Observable 中选择您想要的。

【讨论】:

【参考方案4】:

最可能的问题是,您试图使用从服务返回的通用对象作为类型化对象。我喜欢用.mapObject.assign() 来隐藏东西,像这样:

  getAll()
    return this.db.list('/products').snapshotChanges()
      .pipe(
        map(actions =>
          actions.map(a => (Object.assign(new ClassThatImplementsProductInferface(), a))
        )
      );
  

这假定从snapshotChanges() 返回的数据包含所有数据并且可能是产品接口。

【讨论】:

【参考方案5】:

如果您肯定知道响应类型,则可以快速解决。

(actions as unknown)as Product

【讨论】:

以上是关于键入'键:字符串; ' 不可分配给类型 'Product' Angular 7的主要内容,如果未能解决你的问题,请参考以下文章

键入'可观察<用户 |空 | undefined>' 不可分配给类型 'Observable<User>'

打字稿:如何键入 Ramda R.prop(key) T' 不可分配给类型为 '(s: ) => 的参数

打字稿类型“数字”不可分配│键入“字符串”

打字稿 - 字符串'不可分配给类型'FC

错误:无法分配类型“字符串?”的值键入“字符串?。类型”

如何修复“类型'字符串'不可分配给类型'从不'”?