2016-07-03 127 views
29

派生的类当试图从一个类中node_modules打字稿编译器抛出一个错误扩展类的说法:“可观察<T>”不是从“可观察<T>”

Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.

这只是发生在基类来自node_module

的基类的样子:

import {Observable} from "rxjs/Observable"; 
export abstract class TestBase<T> { 

    request(options: any):Observable<T> { 
     return Observable.throw(new Error('TestBase is abstract class. Extend it and implement own request method')); 
    } 
} 

项目中的子类是:

import {Observable} from "rxjs/Observable"; 
import {TestBase} from "@org/core"; 

class SocketResponse { 

} 

class Socket { 
    request(): Observable<SocketResponse> { 
     return new Observable.of(new SocketResponse()); 
    } 
} 

export class Sub extends TestBase<SocketResponse> { 
    request(options:any):Observable<SocketResponse> { 
     return new Socket().request(); 
    } 
} 

如果基类(TestBase)从node_module移动到项目它的自我与改变导入看起来像 import {TestBase} from "./base";错误消失。

这是由于编译创建每个模块的不同范围的类型?我完全迷失在这里。

更新:

这似乎与npm link链接node_modules时才会发生。 似乎有一种可能的解决方法,就是不用返回基类中的类型来返回接口。

更多信息可以在这里找到:

https://github.com/Microsoft/TypeScript/issues/6496

https://github.com/ReactiveX/rxjs/issues/1744

+2

我认为你是对的。您不能扩展具有全局/环境范围的类。 [Typescript GitHub repo上的此线程](https://github.com/Microsoft/TypeScript/issues/3282)似乎描述了一些解决方法。 – morphatic

+1

即使没有'npm link',我也有这个问题。我尝试使用'npm pack'和'npm install'作为解决方法,但没有骰子。 https://github.com/robertjd/sp-ng2/pull/1 –

+0

@Maxime Raineville的答案为我工作 – vincecampanale

回答

3

我有同样的问题。

我有以下目录结构(angular2项目)

angular 
| 
---- common_files 
     | 
     ----- package.json 
     | 
     ----- index.ts 
     | 
     ----- catalog1 
      | 
      ---- package.json 
      | 
      ---- some_file_with_service_model_comopnent.ts 
      | 
      ---- index.ts - this is regular barrel file 
     | 
     ----- catalog2 
| 
---- app1 
    | 
    ------ package.json 
| 
---- apps 
    | 
    ------ package.json 

在我的共同我已经definied对象和服务:

export class ItemBase {} 

esport class SomeType extends ItemBase {} 

export class ItemServiceBase { 
    public getItems():Observable<ItemBase> { 
     //do something 
    } 
} 

export class SomeService extends ItemServiceBase { 
    //some specific operations can go here 
} 

在我的应用我是用从普通项目如下:

import { SomeType, SomeTypeService } from "warehouse-system/products-settings"; 

class AttributeTypesComponent { 
    private myValues : Observable<SomeType[]>; 
    private service : SomeTypeService; 

    constructor(){ 
     this.service = new SomeTypeService(); 
     this.myValues = <Observable<SomeType[]>> this.service.getItems(); 
    } 
} 

这导致了编译问题: ERROR in [at-loader] src/app/some_file.ts:22:47 Type 'Observable<ItemBase[]>' cannot be converted to type 'Observable<SomeType[]>'. Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.

调查后我改变了myValues的类型,但它仍然没有解决问题。编译问题改为:

ERROR in [at-loader] src/app/some_file.ts:22:47 Type 'Observable<SomeType[]>' cannot be converted to type 'Observable<SomeType[]>'. Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.

最终的解决方案(解决方法)

什么解决我的问题,是 “改写” 观察到的应用程序方面:

this.myValues = Observable.create(subscriber => { 
     this.service.getItems().subscribe(items => subscriber.next(items)); 
    }); 

这是不是很好的解决方法。在我看来,这个问题是由npm/typescript/observables中的一个错误引起的。但直到问题不解决打字机开发方面,您可以使用此解决方法作为解决方案。

11

我在为项目开发自定义模块时遇到了一个非常类似的问题。我不是100%确定我们遇到了同样的问题,但它看起来非常接近。

我如何解决我的问题

我建议你删除文件夹node_modules并重新安装所有的依赖关系。

rm -rf node_modules/ 
npm cache clean 
npm install 

为我解决了这个问题。

什么问题是(我认为)

我开发的模块有这样的主体工程正试图扩展一个抽象类。然而,当试图编译主项目时,编译器会抛出同样的错误。

经过一番探索后,我注意到在将我的模块安装到我的项目中时,NPM会抱怨UNMET PEER DEPENDENCY。当在项目的node_modules里面看时,我注意到我的模块有另一个嵌套在其中的node_modules文件夹,它具有与主项目共享的一些依赖关系。

我对此并不确定,但我认为NPM认为模块期望与主项目共享不同版本的依赖项。

因此,模块内部的抽象类从其自己嵌套的node_modules文件夹引用Observable,而主项目引用顶级node_modules文件夹中的Observable。

更多信息

试图解决我的问题时,提供一些见解对于我这个其他问题:

Why does npm install say I have unmet dependencies?

+0

对于任何寻找解决方案的人来说,这一个为我工作。 – vincecampanale

+0

有类似的问题,删除npm包中的'node_modules'解决了这个问题。好的呼叫伴侣。 –

3

我得到一个疯狂的错误,如

Type 'Observable<MessageEvent>' cannot be converted to type 'Observable<MessageEvent>' 
Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>' 

其原因是npm link(实际上是npm i ../other-project,但它是完全相同的东西)。

我的解决方法是有点欺骗:

(stream as any as Observable<MessageEvent>) 

LOL

3

如果有,你必须添加在主机应用程序的tsconfig路径映射多个node_modules文件夹。只需将@ rxjs/*映射到根节点node_modules/rxjs/*即可。然后一切正常。