【问题标题】:Property 'map' does not exist on type 'Subject<{}>'类型“主题<{}>”上不存在属性“地图”
【发布时间】:2017-02-09 04:31:20
【问题描述】:

所以,我看到过很多关于类似问题的其他帖子,但没有一个解决方案有帮助。

我也在 IntelliJ IDEA 15 中进行此开发,而不是 Visual Studio。我目前正在使用 Typescript 2.0.3。

import { Injectable } from '@angular/core';
import { Effect, StateUpdates, toPayload } from '@ngrx/effects';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/dom/webSocket'
import 'rxjs/add/operator/map';

import { AppState } from '../reducers';
import { NGRXWebSocketService } from '../shared/ngrxWebsocket.service';
import { BASE_URL } from "../shared/ngrxWebsocket.service";

export interface WebsocketMessage {
    data: string
}

@Injectable()
export class WebsocketEffects {

constructor(private updates$:StateUpdates<AppState>,
            private ngrxWebSocketService: NGRXWebSocketService) {
}

@Effect() _recieve$ = this.ngrxWebSocketService.getSubject()
    .map((websocketUpdate: WebsocketMessage) => {
        let message = JSON.parse(websocketUpdate.data);
        return{ type: message.action, payload: message.payload}
    });
}

编辑 1:

这是 NGRXWebsocketService。

import {Injectable} from '@angular/core';
import {$WebSocket, WebSocketConfig} from 'angular2-websocket/angular2-websocket'

export const BASE_URL = 'ws://' + location.hostname + ':9000/socket';

@Injectable()
export class NGRXWebSocketService {
    private socket: $WebSocket;

    constructor() {
        this.socket = new $WebSocket(BASE_URL);
    }

    public sendRequest(request) {
        return this.socket.send(request);
    }

    public reconnect() {
        this.socket = new $WebSocket(BASE_URL);
    }

    public getSubject() {
        return this.socket.getDataStream();
    }
}

【问题讨论】:

  • 如果你这样做getSubject().asObservable().map会发生什么?
  • @peeskillet error TS2339: Property 'map' does not exist on type 'Observable&lt;{}&gt;'.
  • @PaulSwetz 我在我的问题中说我没有使用 Visual Studio。
  • 只是IDE的问题吗?还是你手动编译的时候得到这个?
  • 我可以在 IDE 中很好地运行应用程序。我手动编译时才看到这个问题。

标签: angular rxjs ngrx


【解决方案1】:

这看起来像是手动编译期间的打字问题。

在 IDE 中编译时,IDE 可能有内部类型配置,这在您的项目设置中不存在。

  1. npm install typings -g

  2. 检查您的package.json dependencies

    es6-垫片

    如果您在dependencies 中有es6-shim,请在您的项目目录中创建typings.json

    {
        "globalDependencies": {
            "es6-shim": "registry:dt/es6-shim",
            "node": "registry:dt/node"
        }
    }
    

    核心-js

    如果您在dependencies 中有core-js,请在您的项目目录中创建typings.json

    {
        "globalDependencies": {
            "core-js": "registry:dt/core-js",
            "node": "registry:dt/node"
        }
    }
    
  3. typings install

  4. 尝试手动编译。

【讨论】:

    【解决方案2】:

    在您问题的代码中,您似乎正在执行所需的操作:您已经导入了 Subject 并且您已经导入/添加了 map 运算符。所以你为什么会收到 TypeScript 错误有点神秘。但是,您最近对该问题的编辑确实提出了一种可能性。

    很明显NGRXWebsocketService 导入了一个 NPM 模块:angular2-websocket/angular2-websocket。该模块在rxjs@5.0.0-beta.12 上有一个dependency。请注意,这是 dependency不是 peerDependency

    您的node_modules 层次结构中完全有可能有两个独立的rxjs 模块:一个在您的应用程序中使用(因此在WebsocketEffects 中),另一个在angular2-websocket/angular2-websocket 中使用。如果是这种情况,TypeScript 会认为 getSubject 返回的类型与您导入的类型以及您添加了 map 运算符的类型不同(尽管它们都被称为 Subject)。

    您可以通过在WebsocketEffects 类中添加一些临时代码来验证是否确实如此:

    temp() {
        let subject: Subject<any> = this.ngrxWebSocketService.getSubject();
    }
    

    如果angular2-websocket/angular2-websocket 正在使用单独的rxjs 安装,您应该会看到如下错误:

    TS2322: Type 'Subject<any>' is not assignable to type 'Subject<any>'.
    

    您还可以运行以下 NPM 命令来列出您的 node_modules 目录下的 rxjs 安装:

    npm list rxjs
    

    rxjs 的作者应该解决多个rxjs 模块安装的可能性。但是,如果您确实有多个安装,您可能可以做一些事情(因为rxjs 版本是相同的)。如果您卸载并重新安装angular2-websocket/angular2-websocket,它应该使用您在应用中使用的rxjs 模块(而不是安装它自己的)。

    其实angular2-websocket/angular2-websocket中的所有依赖都应该是对等依赖,而不是依赖。我建议您将此作为issue 提出。

    【讨论】:

      【解决方案3】:

      尝试导入map:

      import {map} from 'rxjs/operator/map';
      

      【讨论】:

        【解决方案4】:

        查看source codeangular2-websocket 看起来getDataStream() 返回一个发出MessageEvent 的主题。

        试试这个:

        @Effect() _receive$ = this.ngrxWebSocketService.getSubject()
          .map((messageEvent: MessageEvent) => {
              let message = JSON.parse(messageEvent.data);
              return { type: message['action'], payload: message['payload'] };
          });
        

        【讨论】:

          【解决方案5】:

          对于 RXJS v6,您必须使用 pipe() 和 map()。

           this.ngrxWebSocketService.getSubject().pipe(
              map((websocketUpdate: WebsocketMessage) => {
                  let message = JSON.parse(websocketUpdate.data);
                  return{ type: message.action, payload: message.payload}
              }) 
           );
          

          希望这个修复会有所帮助。

          【讨论】:

            【解决方案6】:

            import 'rxjs/Rx'; 应该可以解决所有问题

            【讨论】:

              【解决方案7】:

              我试试:

              import 'rxjs/add/operator/map'
              

              从这里: https://github.com/webmaxru/pwa-workshop-angular/issues/2 并且工作正常:)

              【讨论】:

                【解决方案8】:

                https://medium.com/coding-snippets/rxjs-5-5-property-map-does-not-exist

                这有助于我使用当前版本的 angular 和 rxjs。 基本上你需要使用pipe而不是map,并在pipe内调用rxjs的map函数

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-01-11
                  • 2020-05-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-03
                  • 2022-01-26
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多