mac*_*tyr 5 rxjs typescript rxjs5 angular
使用Angular 4.1.3,rxjs 5.3.0,打字稿2.2.2的示例代码:
import { Subject } from 'rxjs'
export class Example {
public response$: Subject<boolean>;
public confirm(prompt: string): Subject<boolean> {
// ...set up a confirmation dialog...
this.response$ = new Subject<boolean>();
return this.response$.first();
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此代码时,打字稿抱怨最后一行:
The 'this' context of type 'Subject<boolean>' is not assignable to method's 'this' of type 'Observable<boolean>'.
Types of property 'lift' are incompatible.
Type '<R>(operator: Operator<boolean, R>) => Observable<boolean>' is not assignable to type '<R>(operator: Operator<boolean, R>) => Observable<R>'.
Type 'Observable<boolean>' is not assignable to type 'Observable<R>'.
Type 'boolean' is not assignable to type 'R'.
Run Code Online (Sandbox Code Playgroud)
我的意思是说这first()是一种可观察的方法,而不是主题,但是我的理解是,主题也是一种可观察的方法,所以这应该不是问题。而且,实际上,如果我忽略该错误,则代码可以编译并正常运行。
我尝试过的事情:
first显式导入运算符的各种方式,例如import 'rxjs/add/operator/first'。这不会更改错误。first(),例如return (this.response$ as Observable<boolean>).first();。这导致一个不同但相似的错误,对我来说似乎也不正确:Type 'Observable<boolean>' is not assignable to type 'Subject<boolean>'. Property 'observers' is missing in type 'Observable<boolean>'.如何说服打字稿调用first()主题是有效的?
为了响应下面对返回类型的讨论而澄清:该方法可能还具有不正确的返回类型(应该是可观察的,而不是主题),但这似乎是一个单独的问题;更改返回类型不能解决上述错误。确认这一点的进一步细节是,当vscode突出显示错误时,它仅突出显示this.response$,而不是整个返回行,这表明问题出在this.response$和之间first(),而不是在first()函数签名之间:
TL;DR: TypeScript 2.4 中引入的更严格的类型检查与 RxJS < 5.4.2 不兼容(由于错误)。您的 IDE 可能使用 TypeScript >= 2.4 进行类型检查。升级 RxJS(推荐)、降级 TypeScript,或者将编程解决方案Subject.asObservable与返回类型一起使用Observable<boolean>。
解释:
讨论结束后,我查看了 RxJS 5.3.0 源代码,发现和之间的签名lift不同。具体来说,我们可以看到以下区别:SubjectObservable
lift<R>(operator: Operator<T, R>): Observable<T>
Run Code Online (Sandbox Code Playgroud)
lift<R>(operator: Operator<T, R>): Observable<R>
Run Code Online (Sandbox Code Playgroud)
返回的 Observable 的通用类型是T in Subject,但R in Observable。
该first()运算符需要 anObservable作为其上下文,但由于 的签名this不匹配,因此无法匹配。这对我来说很奇怪,因为它扩展了,因此它的所有属性都应该有匹配的签名。SubjectliftSubjectObservable
现在这里是解决方案:TypeScript 在 2.4 版本中引入了更严格的类型检查,实际上 RxJS 需要通过更改方法的签名来赶上这一变化lift。此更改可以在版本5.4.2的更改日志中看到:
主题:提升签名现在适用于更严格的 TypeScript 2.4 检查
这是对应的问题。这似乎是一个错误。
您正在运行 RxJS 5.3,所以这就是您收到错误的原因。
有两种选择。升级 RxJS(推荐)或使用Subject.asObservable将类型从 更改Subject为Observable.
正如我的评论中提到的,函数的返回类型需要更改为Observable<boolean>。
应用于您的剪裁,应该如下所示:
public confirm(prompt: string): Observable<boolean> {
// ...set up a confirmation dialog...
this.response$ = new Subject<boolean>();
return this.response$.asObservable().first();
}
Run Code Online (Sandbox Code Playgroud)
我看到您的 TypeScript 版本是2.2,但您的 IDE 很可能使用另一个 TypeScript 版本进行类型检查。
选择
正如@cartant提到的,Subject.lift实现返回一个Subject,但是不能用 TypeScript 的类型来表达(没有返回类型重载,甚至不确定是否有支持它的语言)。
因此,另一个解决方案是通过强制转换为 来忽略类型检查<any>。这样你也可以回来Subject。
| 归档时间: |
|
| 查看次数: |
273 次 |
| 最近记录: |