使用 RxJS 将一种对象类型转换为另一种对象类型

时间:2021-07-23 11:18:14

标签: angular typescript rxjs

我有以下型号:

export interface IdName { 
    id: number;
    name: string;
}

export interface Product { 
    id: number;
    name: string;
    currency?: string;
    additionalData: any;
}

我想在 Angular/Typescript 中将 Observable 转换为 Observable。我试过了

getData() : Observable<IdName[]> {

        // Note: getProducts returns Observable<Product[]>

        this.productService.getProducts().pipe(
            return map((product: Product) => {
                {id: product.id, name: product.name}
            });
        );

    }

但是,它显示了一些语法错误。我该如何解决?

4 个答案:

答案 0 :(得分:1)

您放错了 return 语句和分号。

应该是:

return this.productService.getProducts().pipe(
  map((product: Product) => {
    return {id: product.id, name: product.name}
  })
);

pipe() 采用定义为 operator(input => output) 或扩展 operator(input => { return output; })

的操作列表(可变参数)

答案 1 :(得分:1)

您的箭头函数和 RxJS map 运算符的用法存在语法错误。

注意以下事项

const Func = (param: Product) => ({ id: param.id, name: param.name })

相当于

const Func = (param: Product) => { 
  return { id: param.id, name: param.name }
};

我看到以下问题:

  1. return 语句位置错误。 RxJS map 运算符没有明确返回任何内容。它已经返回了包含修改数据的源 observable。
  2. 类型签名错误。如果它是一个 Product 数组,它必须是 Product[]。您需要使用 Javascript Array#map 来转换 Product[] 数组。
  3. 您还缺少用于实际转换为另一种类型的 Typescript type assertion

试试下面的方法

getData(): Observable<IdName[]> {
  return this.productService.getProducts().pipe(
    map((products: Product[]) =>            // <-- no return here, this is RxJS `map` operator 
      products.map((product: Product) => {  // <-- Javascript `Array#map` function
        return { 
          id: product.id, 
          name: product.name 
        } as IdName;                        // <-- assert type using Typescript `as`
      })
    )                                       // <-- no semi-colon here
  );
}

答案 2 :(得分:1)

你有一些错别字,改成:

getData(): Observable<IdName[]> {
    return this.productService.getProducts().pipe(
       map((products: Product[]) => {

         return products.map(product => ({
           id: product.id,
           name: product.name
         } as IdName));
       })
    );
}

答案 3 :(得分:1)

你必须在这里使用一个函数吗?您可以将其分配给类型为 Observable<IdName> 的变量。此外,您仍然需要映射发出的数组中的每个产品。

this.getData$ = this.productService.getProducts().pipe(
  map(products=>
    products.map({id, name}) => ({id, name}) as IdName)
  )
)

需要注意的几点:

  • map() 运算符将推断从强类型 observable 发出的类型,因此您无需将产品重新声明为 Product[]
  • 当您只需要引用对象的某些属性时,对象解构是您的朋友。这就是数组映射引用 ({id, name})
  • 的原因