web-dev-qa-db-ja.com

「Observable <T>」は「Observable <T>」から派生したクラスではありません

node_modulesのクラスからクラスを拡張しようとすると、TypeScriptコンパイラは次のエラーをスローします。

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";のように変更すると、エラーが消えます。

これは、コンパイルによって各モジュールの異なるスコープに型が作成されるためですか?ここで完全に迷ってしまいました。

更新:

これは、node_modulesnpm linkとリンクする場合にのみ発生するようです。現時点で考えられる回避策の1つは、基本クラスで型を返す代わりにインターフェイスを返すことです。

詳細についてはこちらをご覧ください。

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

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

38
fredrik

プロジェクトのカスタムモジュールを開発しているときに、非常によく似た問題に遭遇しました。私たちが同じ問題を抱えているとは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を参照していました。

詳しくは

この他の質問は、私の問題を解決しようとするとき、私にいくつかの洞察を与えました:

なぜnpmインストールは依存関係が満たされていないと言うのですか?

15

同じ問題が発生しました。

次のカタログ構造があります(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

私の共通では、オブジェクトとサービスを定義しました:

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のバグが原因です。ただし、TypeScript開発者側で問題が解決しない限り、この回避策を解決策として使用できます。

6
Maciej Treder

Node_modulesフォルダーが複数ある場合は、ホストアプリのtsconfigにパスマッピングを追加する必要があります。 @ rxjs/*をルートnode_modules/rxjs/*にマップするだけです。その後、すべてが正常に動作します。

6
David Ibl

この問題は、npmリンクを実行する場合にのみ発生します。

クライアントプロジェクトのtsconfig.jsonのcompilerOptionsにパスを追加します

"paths": { "rxjs/*": ["../node_modules/rxjs/*"]}

これは、rxjs依存関係からのパスを指定するので機能するはずです。

3
jitenderd

私は次のようなクレイジーなエラーを受け取っていました

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
André

Tsconfig.jsonにパスマッピングを追加して、依存関係のrxjsをnode_modulesフォルダーのrxjsにマッピングできます。

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "rxjs": ["node_modules/rxjs"]
    }
}

より多くのドキュメントが TypeScriptサイト で利用可能です

1
JusMalcolm

Rxjsモジュールをリストした後:

npmリストrxjs

+-@ angular/cli @ 1.6.6 | +-@ angular-devkit/core @ 0.0.29 | | -- [email protected] | +-- @angular-devkit/[email protected] | |-- [email protected] | -- [email protected][email protected]

同じモジュールの2つのバージョンを見ることができます。私のプロジェクトでは、rxjsの下位バージョンが必要でした。 anglular/cliにはrxjsの上位バージョンが必要です。

以前は問題は発生していませんでしたが、突然同じ依存関係を持つすべてのプロジェクトが同じTS90010エラーをスローしました:

[at-loader]のエラー./src/main/webapp/app/admin/user-management/user-management-detail.component.ts:23:9 TS90010:タイプ 'Subscription'は、タイプ 'Subscription'に割り当てられません。この名前を持つ2つの異なるタイプが存在しますが、それらは無関係です。

プロパティ「_parent」は保護されていますが、タイプ「Subscription」は「Subscription」から派生したクラスではありません。

最後に、package.jsonのTypeScriptバージョンを2.6.2から2.9.2に更新し、すべてのエラーが消えました。

0
Bart Gluszak