"Наблюдаемый <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/*. Тогда все работает нормально.