47 votes

Observable<T>' n'est pas une classe dérivée de 'Observable<T>'.

Lorsque l'on essaie d'étendre une classe à partir d'une classe dans une node_modules le compilateur de typescript jette une erreur disant :

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

Cela ne se produit que lorsque la classe de base est issue d'une node_module .

La classe de base ressemble :

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'));
    }
}

Le sous-classer dans un projet :

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();
    }
}

Si la classe de base ( TestBase ) est déplacé de la node_module au projet lui-même et changez l'importation pour qu'elle ressemble à ceci import {TestBase} from "./base"; L'erreur disparaît.

Est-ce dû au fait que la compilation crée les types dans différents scopes pour chaque module ? Je suis complètement perdu là.

Mise à jour :

Cela semble se produire uniquement lors de l'établissement d'un lien entre le node_modules con npm link . Il semble qu'une solution possible pour le moment soit de retourner une interface au lieu d'un type dans la classe de base.

Vous trouverez de plus amples informations ici :

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

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

2 votes

Je pense que tu as raison. Vous ne pouvez pas étendre les classes qui ont une portée globale/ambiante. Ce fil de discussion sur le repo GitHub de Typescript semble décrire quelques solutions de contournement.

1 votes

J'ai ce problème même sans npm link . J'ai essayé d'utiliser npm pack y npm install comme solution de rechange, mais pas de résultat. github.com/robertjd/sp-ng2/pull/1

0 votes

La réponse de @Maxime Raineville a fonctionné pour moi

18voto

Maxime Rainville Points 1326

Je viens de rencontrer un problème très similaire en développant un module personnalisé pour un projet. Je ne suis pas sûr à 100% que nous avions le même problème, mais cela semble assez proche.

Comment j'ai résolu mon problème

Je vous suggère d'effacer votre node_modules et réinstaller toutes vos dépendances.

rm -rf node_modules/
npm cache clean
npm install

Cela a résolu le problème pour moi.

Quel était le problème (je pense)

Le module que je développais avait une classe abstraite que le projet principal essayait d'étendre. Cependant, lorsque j'essayais de compiler le projet principal, le compilateur lançait la même erreur que celle que vous obtenez.

Après avoir creusé un peu, j'ai remarqué que NPM se plaignait de la présence d'une UNMET PEER DEPENDENCY lors de l'installation de mon module dans mon projet. En regardant à l'intérieur du node_modules du projet, j'ai remarqué que mon module avait un autre node_modules imbriqué à l'intérieur de celui-ci avec quelques dépendances qu'il partage avec le projet principal.

Je ne suis pas certain de cela, mais je pense que NPM a pensé que le module attendait une version différente des dépendances qu'il partageait avec le projet principal.

Ainsi, la classe abstraite du module faisait référence à Observable à partir de sa propre classe imbriquée. node_modules alors que le projet principal faisait référence à Observable à partir du dossier de niveau supérieur node_modules dossier.

Plus d'informations

Ces autres questions m'ont donné un aperçu de la situation lorsque j'ai essayé de résoudre mon problème :

Pourquoi npm install dit que j'ai des dépendances non satisfaites ?

0 votes

J'ai eu le même problème, en supprimant node_modules dans le paquet npm a résolu le problème. Bien vu, mon pote.

0 votes

Si cela ne fonctionne pas, essayez stackoverflow.com/a/51033056/1279758

7voto

David Ibl Points 583

S'il y a plusieurs dossiers node_modules, vous devez ajouter un mappage de chemin dans le tsconfig de l'application hôte. Il suffit d'affecter @rxjs/* au dossier racine node_modules/rxjs/*. Ensuite, tout fonctionne bien.

3 votes

Qu'est-ce que cela signifie ? Comment pouvons-nous faire cela ?

0 votes

En attendant que mon montage soit revu par des pairs, voici le lien vers la solution : github.com/Microsoft/typescript/issues/

6voto

Maciej Treder Points 4569

J'ai le même problème.

J'ai la structure de catalogue suivante (projet 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

Dans ma commune, j'ai défini des objets et des services :

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
}

Dans mes applications, j'utilisais des éléments communs comme suit :

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();
  }
}

Cela causait des problèmes de compilation : 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>'.

Après enquête, j'ai changé de type de myValues mais ça ne résout toujours pas le problème. Les problèmes de compilation ont été modifiés :

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>'.

La solution finale (solution de contournement)

Ce qui a résolu mon problème, c'est la "réécriture" de l'observable du côté de l'application :

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

Ce n'est pas vraiment une bonne façon de résoudre le problème. A mon avis, ce problème est causé par un bug dans npm/typescript/observables. Mais tant que le problème n'est pas résolu du côté des développeurs de typescript, vous pouvez utiliser cette solution de contournement comme solution.

5voto

jitenderd Points 39

Le problème ne se produit que lorsque vous faites le lien npm.

Ajouter des chemins aux compilerOptions du tsconfig.json du projet client.

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

Cela devrait fonctionner car cela spécifiera le chemin à partir de la dépendance de rxjs.

0 votes

Brillant ! Tout le monde oublie toujours le /* qui semble être nécessaire !

0 votes

Ne parcourez pas cette réponse trop rapidement, notez que compilerOptions est une propriété de niveau racine dans votre fichier tsconfig.json . Notez également que votre paths Les valeurs *doivent être relatives à votre baseUrl qui doit exister dans compilerOptions .

4voto

André Points 3224

J'obtenais une erreur bizarre du genre

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>'

Et la raison était npm link (en fait npm i ../other-project mais c'est tout à fait la même chose).

Ma solution de contournement était une sorte de tricherie :

(stream as any as Observable<MessageEvent>)

LOL

0 votes

Comment était npm link le problème, et qu'est-ce que vous pourriez faire d'autre que ce piratage du code ?

0 votes

Typescript pense que MessageEvent importé dans mon code est différent de la même classe dans le module lié, d'où l'erreur. Vous pourriez npm pack la librairie avant de l'installer, donc vous n'aurez pas de lien, ou vous pouvez essayer les autres réponses dans ce post.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X