什么是<r>中的R(观察者:观察者<r>)=&gt;订阅|功能|空虚

时间:2017-08-07 04:43:03

标签: typescript observers typescript-generics

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'类型。

This answer帮助强化了我认为我已经知道的关于<T>和打字稿中的泛型的内容,但是什么是<R>

(完整的错误消息)

  

类型的参数'(obs:Observer)=&gt;空虚'不是   可分配给'((observer:Observer)=&gt; void |类型的参数   功能|订阅)|未定义”。输入'(obs:   观察者)=&gt; void'不能分配给类型   '(观察员:观察者)=&gt;无效|功能|订阅'。类型   参数'obs'和'observer'是不相容的。类型   “观察者”不能分配给类型   “观察员”。类型“R”不能分配给类型   'UploadTaskSnapshot'。

3 个答案:

答案 0 :(得分:3)

在英语中,<R>(observer: Observer<R>) => Subscription | Function | void表示:

  

对于任何类型R,一个可以将R的Observer转换为Subscription或函数或者什么都没有的函数

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

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

用英语表示:

  

获取Observer<UploadTaskSnapshot>并返回

的函数

因为它不是一个函数,它会将R的观察者视为任何类型的R 并且喜欢它。这个功能在观察者中具有独特的味道,构造者无法容纳它。

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

答案 1 :(得分:0)

在这种情况下,

<T><R>是在TypeScripts中使用generics的示例。

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

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

然后,您可以通过在使用时指定T来使用一般。在这种情况下,我们说我们指定TUser类型:

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;

答案 2 :(得分:0)

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

这个问题是另一个类型变量,您可以给您想要的任何字母,但是在这种情况下,首先,您有两个类型变量,因此您需要两个不同的字母,其次,为什么要使用字母R?因为您想说这个类型变量是一个请求类型,就像您使用T来说这个类型变量是一个类型