0

Angularfire2 项目有一个正在进行的分支,添加了一个存储功能。两个新文件包括一个 Observable 类和一个 Factory 函数。

可观察类

export class FirebaseUploadTaskObservable<T> extends Observable<T> {

  constructor(
    subscribe?: <R>(observer: Observer<R>) => Subscription | Function | void, 
    public uploadTask?:firebase.storage.UploadTask) {
      super(subscribe);
  }

  lift<T, R>(operator: Operator<T, R>): Observable<R> {
    const observable = new FirebaseUploadTaskObservable<R>();
    observable.source = this;
    observable.operator = operator;
    observable.uploadTask = this.uploadTask;
    return observable;
  }
  ...
}

工厂功能

export function FirebaseUploadTaskFactory (uploadTask: UploadTask):
  FirebaseUploadTaskObservable<UploadTaskSnapshot> {

  const obsFunction = (obs: Observer<UploadTaskSnapshot>) => { ... };

  const objectObservable = new FirebaseUploadTaskObservable(obsFunction, uploadTask);

  ...
}

简而言之,我得到的错误是:

类型“R”不可分配给类型“UploadTaskSnapshot”。

这个答案有助于强化我认为我已经知道<T>的 Typescript 和泛型,但什么是<R>?

(完整的错误信息)

'(obs: Observer) => void' 类型的参数不能分配给 '((observer: Observer) => void | Function | Subscription) | 类型的参数 不明确的'。类型 '(obs: Observer) => void' 不可分配给类型 '(observer: Observer) => void | 功能 | 订阅'。参数 'obs' 和 'observer' 的类型不兼容。类型“观察者”不可分配给类型“观察者”。类型“R”不可分配给类型“UploadTaskSnapshot”。

4

3 回答 3

3

在英语中,<R>(observer: Observer<R>) => Subscription | Function | void意思是:

对于任何类型的 R,一个可以将 R 的观察者变成订阅或函数或什么都没有的函数

现在,您的构造函数具有签名constructor(subscribe?: <R>(...。这意味着它需要一个具有上述属性的函数,即它需要一个对任何类型的观察者都满意的函数。例如,此构造函数不会满足于:

const obsFunction = (obs: Observer<UploadTaskSnapshot>) => { ... }

在英语中是:

接受一个Observer<UploadTaskSnapshot>并返回一些东西的函数

因为它不是一个函数,它不会为任何类型的 R接受 R 的观察者并喜欢它。这个函数对观察者有一种特殊的品味,构造函数无法适应。

其他答案提供了一些关于如何解决问题的指示,但我相信您的<R>参数在这里可能是多余的。你可能只是想要(observer: Observer<T>).

于 2017-08-07T06:16:45.327 回答
0

我是 TypeScript 的新手,我从 TypeScript 泛型中学到的是它只是一个类型变量,我们使用 T 来捕获类型,而不是值。

对于这个问题,是另一个类型变量,你可以给任何你想要的字母,但是对于这种情况,首先,你有两个类型变量,所以你需要两个不同的字母,第二,为什么使用字母 R?因为你想说这个类型变量是一个请求类型,就像你用 T 说这个类型变量是一个类型一样

于 2019-01-02T14:35:29.293 回答
0

<T>在这种情况下,是在 TypeScripts<R>中使用泛型的示例。

泛型的快速总结。您可以使用泛型类型参数声明接口/类/函数,如下所示:

class List<T> {
  getItem(position: number): T { ... }
  addItem(item: T): void { ... }
}

然后您可以通过指定使用它的时间来通用地T使用它。在这种情况下,我们说我们指定T为 type User

let x = new List<User>(); // a list of Users;
x.addItem(myUser);  // we expect this to take an item of type User
x.getItem(0); // we expect this to return a number;
于 2017-08-07T05:57:53.770 回答