"Наблюдаемый <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"; Ошибка исчезнет.

Это связано с тем, что компиляторы создают типы в разных областях для каждого модуля? Я здесь полностью потерян.

Update:

Это происходит только при связывании node_modules с npm link. Кажется, что одно возможное обходное решение на данный момент - это вместо того, чтобы возвращать тип в базовом классе для возврата интерфейса.

Более подробную информацию можно найти здесь:

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

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

Ответ 1

Я просто столкнулся с очень похожими проблемами при разработке пользовательского модуля для проекта. Я не уверен на 100%, что у нас была такая же проблема, но она выглядит довольно близко.

Как я решил свою проблему

Я бы предложил удалить вашу папку node_modules и переустановить все ваши зависимости.

rm -rf node_modules/
npm cache clean
npm install

Это решило это для меня.

Какая проблема была (я думаю)

Модуль, который я разрабатывал, имел абстрактный класс, который основной проект пытался расширить. Однако, пытаясь скомпилировать основной проект, компилятор выдаст ту же ошибку, которую вы получаете.

После небольшого копания я заметил, что NPM будет жаловаться на UNMET PEER DEPENDENCY при установке моего модуля в мой проект. Когда я смотрел в node_modules проекта, я заметил, что в моем модуле есть другая папка node_modules, вложенная внутри нее, с некоторыми зависимостями, которые она разделяет с основным проектом.

Я не уверен в этом, но я думаю, что NPM полагает, что модуль ожидает различную версию зависимостей, которые он разделяет с основным проектом.

Таким образом, абстрактный класс внутри модуля ссылался на Observable из собственной вложенной папки node_modules, в то время как основной проект ссылался на Observable из папки верхнего уровня node_modules.

Дополнительная информация

Эти другие вопросы дали мне некоторое представление о том, как решить мою проблему:

Почему установка npm говорит, что у меня есть неудовлетворенные зависимости?

Ответ 2

У меня такая же проблема.

У меня есть следующая структура каталогов (проект 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, вы можете использовать это обходное решение как решение.

Ответ 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

Ответ 4

Если существует несколько папок node_modules, вам нужно добавить сопоставление пути в главном приложении tsconfig. Просто сопоставьте @rxjs/* с корнем node_modules/rxjs/*. Тогда все работает нормально.