【问题标题】:'Observable<T>' is not a class derived from 'Observable<T>''Observable<T>' 不是从 'Observable<T>' 派生的类
【发布时间】:2016-11-05 05:36:11
【问题描述】:

当试图从 node_modules 中的类扩展一个类时,打字稿编译器会抛出一个错误:

Property 'source' is protected but type 'Observable&lt;T&gt;' is not a class derived from 'Observable&lt;T&gt;'.

仅当基类来自 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 链接时发生。 目前似乎一种可能的解决方法是在基类中返回一个接口而不是返回一个类型。

更多信息可以在这里找到:

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

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

【问题讨论】:

标签: typescript rxjs5


【解决方案1】:

我在为项目开发自定义模块时遇到了一个非常相似的问题。我不能 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。

更多信息

在尝试解决我的问题时,这些其他问题为我提供了一些见解:

Why does npm install say I have unmet dependencies?

【讨论】:

【解决方案2】:

如果有多个 node_modules 文件夹,您必须在主机应用程序的 tsconfig 中添加路径映射。只需将 @rxjs/* 映射到根 node_modules/rxjs/*。然后一切正常。

【讨论】:

【解决方案3】:

我遇到了同样的问题。

我有以下目录结构(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 中的错误引起的。但是直到问题在打字稿开发者方面没有解决之前,您可以使用此解决方法作为解决方案。

【讨论】:

    【解决方案4】:

    您可以在 tsconfig.json 中添加路径映射,以将依赖项中的 rxjs 映射到 node_modules 文件夹中的那个:

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

    更多文档请访问Typescript site

    【讨论】:

      【解决方案5】:

      仅当您执行 npm 链接时才会出现此问题。

      添加路径到客户端项目的tsconfig.json的compilerOptions

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

      这应该可以工作,因为它将指定来自 rxjs 依赖项的路径。

      【讨论】:

      【解决方案6】:

      我遇到了一个疯狂的错误,比如

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

      哈哈

      【讨论】:

      • npm link 的问题是什么,除了这个 hack 代码你还能做什么?
      • Typescript 认为在我的代码中导入的 MessageEvent 与链接模块中的同一类不同,因此出现错误。你可以在安装之前npm pack lib,这样你就没有链接,或者你可以尝试这篇文章中的其他答案。
      【解决方案7】:

      列出 rxjs 模块后:

      npm 列表 rxjs

      +-- @angular/cli@1.6.6 | +-- @angular-devkit/core@0.0.29 | | -- rxjs@5.5.10 | +-- @angular-devkit/schematics@0.0.52 | |-- rxjs@5.5.10 | -- rxjs@5.5.10 -- rxjs@5.5.6

      您可以看到同一模块的 2 个版本。我的项目需要较低版本的 rxjs,例如angular/cli 需要更高版本的 rxjs。

      它之前没有引起任何问题,但是突然之间所有具有相同依赖项的项目都抛出了相同的 TS90010 错误,例如:

      [at-loader] 中的错误 ./src/main/webapp/app/admin/user-management/user-management-detail.component.ts:23:9 TS90010:“订阅”类型不可分配给“订阅”类型。存在同名的两种不同类型,但它们不相关。

      属性“_parent”受到保护,但类型“订阅”不是从“订阅”派生的类。

      最后,我将 package.json 中的 typescript 版本从 2.6.2 更新到 2.9.2,所有错误都消失了。

      【讨论】:

      • 这解决了我的问题。我使用的其中一个库对 rxjs 的依赖性高于 Angular。我看到了所需的确切版本,将 rxjs 更新到该版本,问题已经解决。非常感谢。
      【解决方案8】:

      对我来说,这是我的编辑器问题。 VSCode 包含了来自声明文件 (*.d.ts) 的导入,而实际的类在另一个地方。

      我用实际的类文件导入替换了声明文件导入。

      【讨论】:

        【解决方案9】:

        在monorepo中经常发生确认所有使用的包版本是一致的。

        比如"package-a": "1.5.0",另外一个包中的packageA就是"pacakge-a": "1.4.5"

        【讨论】:

          【解决方案10】:

          其实这个问题可能是因为你的 typescript 版本改变了

          尝试更改您的打字稿版本

          1. 你可以在

            package.json

          设置为2.4.3

          1. 如果不起作用,那么只需尝试 cli

            npm unlink typescript

            npm install typescript@2.3.4

          安装完成后 包.json

          请检查 它应该是工作 在依赖项中

          “依赖”:{
          "@angular/animations": "^5.2.0",
          "@angular/common": "^5.2.0",
          “@angular/compiler”:“^5.2.0”,
          “@angular/core”:“^5.2.0”,
          “@angular/forms”:“^5.2.0” ,
          "@angular/http": "^5.2.0",
          "@angular/platform-b​​rowser": "^5.2.0",
          "@angular/platform-b​​rowser-dynamic": "^5.2.0",
          "@angular/路由器": "^5.2.0",
          "core-js": "^2.4.1",
          "rxjs": "5.4.3",
          “打字稿”:“^2.3.4”,“zone.js”:“^0.8.19”

          但有一点很清楚,这不是错误,这是由于环境变化造成的

          如果仍然遇到问题,请尝试 重新安装节点模块

          祝你好运......

          【讨论】:

            猜你喜欢
            • 2019-08-24
            • 1970-01-01
            • 2019-08-05
            • 2017-12-29
            • 2019-01-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多