类型“主题<>”上不存在属性“地图”

Posted

技术标签:

【中文标题】类型“主题<>”上不存在属性“地图”【英文标题】: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 中很好地运行应用程序。我手动编译时才看到这个问题。 【参考方案1】:

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

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

    npm install typings -g

    检查您的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"
        
    
    

    typings install

    尝试手动编译。

【讨论】:

【参考方案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 code 的angular2-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函数

【讨论】:

以上是关于类型“主题<>”上不存在属性“地图”的主要内容,如果未能解决你的问题,请参考以下文章

“从不”类型上不存在属性“地图”

“对象”类型上不存在 Angular 6 属性“地图”

Subject<MessageEvent> 类型上不存在专有“地图”

类型“typeof ...”上不存在属性“use”,类型“typeof”上不存在属性“extend”

TypeScript:类型“”上不存在属性

错误 TS2339:类型“”上不存在属性“包含”