Lorsque vous tentez d'étendre une classe à partir d'une classe dans un node_modules
, le compilateur TypeScript génère une erreur en disant:
Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.
Cela se produit uniquement lorsque la classe de base provient d'un 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'));
}
}
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ée du node_module
vers le projet, modifiez-la et changez l'importation pour qu'elle ressemble à import {TestBase} from "./base";
L'erreur disparaît.
Est-ce dû à cela que les compilations créent les types dans différentes portées pour chaque module? Je suis complètement perdu ici.
Mettre à jour:
Cela semble se produire uniquement lorsque vous associez le node_modules
au npm link
. Une solution de contournement possible pour le moment consiste à renvoyer un type dans la classe de base pour renvoyer une interface.
Plus d'informations peuvent être trouvées ici:
Je viens de rencontrer un problème très similaire lors du développement d'un module personnalisé pour un projet. Je ne suis pas sûr à 100% que nous ayons le même problème, mais cela semble assez proche.
Je suggère de supprimer votre dossier node_modules
et de réinstaller toutes vos dépendances.
rm -rf node_modules/
npm cache clean
npm install
Cela l'a résolu pour moi.
Le module que je développais comportait un cours abstrait que le projet principal tentait d'étendre. Toutefois, lorsqu’il tente de compiler le projet principal, le compilateur génère la même erreur que vous obtenez.
Après avoir fouillé un peu, j'ai remarqué que NPM se plaignait d'un 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 contenait un autre dossier node_modules
imbriqué avec certaines dépendances qu'il partageait avec le projet principal.
Je n'en suis pas certain, mais je pense que NPM pensait que le module s'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 son propre dossier imbriqué node_modules
alors que le projet principal faisait référence à Observable à partir du dossier node_modules
de niveau supérieur.
Ces autres questions m'ont permis de mieux comprendre mon problème:
Pourquoi npm install dit-il que j'ai des dépendances non satisfaites?
S'il existe plusieurs dossiers node_modules, vous devez ajouter un mappage de chemin dans le fichier tsconfig de l'application hôte. Mappez simplement @ rxjs/* sur la racine node_modules/rxjs/*. Alors tout fonctionne bien.
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 mon commun, 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 courants 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é le type de myValues
mais cela ne résout toujours pas le problème. Problèmes de compilation modifiés en:
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" 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 le résoudre. À mon avis, ce problème est dû à un bogue dans npm/TypeScript/observables. Mais jusqu'à ce que le problème ne soit pas résolu du côté des développeurs TypeScript, vous pouvez utiliser cette solution de contournement comme solution.
Le problème ne se produira que lorsque vous établissez un lien npm.
Ajouter des chemins aux options compilerOptions du fichier tsconfig.json du projet client
"paths": { "rxjs/*": ["../node_modules/rxjs/*"]}
Cela devrait fonctionner car cela spécifierait le chemin depuis la dépendance de rxjs.
Je devenais une folle erreur comme
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 réalité npm i ../other-project
mais c'est à peu près la même chose).
Ma solution était un peu la triche:
(stream as any as Observable<MessageEvent>)
LOL
Après avoir répertorié les modules rxjs:
npm list rxjs
+ - @ angular/cli @ 1.6.6 | + - @ angular-devkit/core @ 0.0.29 | |
-- [email protected] | +-- @angular-devkit/[email protected] | |
-- [email protected] |-- [email protected]
-- [email protected]
Vous pouvez voir 2 versions du même module. Mon projet nécessitait une version inférieure de rxjs, et par exemple anglular/cli nécessite une version supérieure de rxjs.
Cela n’avait posé aucun problème auparavant, mais tous les projets avec les mêmes dépendances généraient les mêmes erreurs TS90010, par exemple:
ERREUR dans [at-loader] ./src/main/webapp/app/admin/user-management/user-management-detail.component.ts:23:9 TS90010: Le type 'Abonnement' n'est pas assignable au type 'Abonnement'. Deux types différents portant ce nom existent, mais ils ne sont pas liés.
La propriété '_parent' est protégée, mais le type 'Subscription' n'est pas une classe dérivée de 'Subscription'.
Enfin, j'ai mis à jour la version de TypeScript dans package.json de 2.6.2 à 2.9.2 et toutes les erreurs ont disparu.
Vous pouvez ajouter un mappage de chemin dans votre tsconfig.json pour mapper les rxjs de votre dépendance à celui de votre dossier node_modules:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"rxjs": ["node_modules/rxjs"]
}
}
plus de documentation est disponible sur le site TypeScript