我有以下型號:
export interface IModel<T> {
exp: number,
value: T
}
我想創建一個自定義的 RxJS 運算子,例如:
private customOperator<U extends A | B, T extends IModel<U>>(custom: Observable<T>): Observable<U> {
return custom.pipe(map((x: T) => x.value ));
}
但是我在使用它時有一個型別錯誤:
mySub: = new Subject<IModel<A>>;
myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator); // <== ERROR
錯誤:無法分配型別 'Observable<A | B>' 輸入'Observable< A>'。
關于如何更改自定義運算子以避免該問題的任何想法?
uj5u.com熱心網友回復:
將運算子包裝在工廠函式中。
private customOperator<T extends IModel<U>, U extends A | B> () {
return (custom: Observable<T>): Observable<U> =>
custom.pipe(map((x: T) => x.value ));
}
然后在管道中使用運算子作為函式呼叫而不是函式 ref。
myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator());
干杯
uj5u.com熱心網友回復:
您需要使用 Typescript型別斷言功能。
你的情況編譯器會抱怨,因為myObs$ 必須有型別的Observable<A>,而你的運營商定制可以回傳任何一個Observable<A> 或一個Observable<B>。
因此,如果您想避免該錯誤,您需要向 Typescript 保證您的自定義運算子肯定會回傳一個Observable<A>. 這是一種避免對 Typescript 編譯器進行合法檢查的技巧,因此您最好確保自己在做正確的事情。
所以代碼應該是這樣的
myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator) as Observable<A>;
或者,更簡單地說
myObs$ = this.mySub.asObservable().pipe(this.customOperator) as Observable<A>;
如果你將滑鼠懸停myObs$在 VSCode 上,你會看到推斷的型別myObs$實際上是Observable<A>即使你沒有指定型別(至少在代碼的最后一個版本中)
基于@akotech 回應的更新
處理這種情況的更好方法是@akotech 提出的方法。
customOperator 如下編碼回傳一個 Observable<U>
private customOperator<T extends IModel<U>, U extends A | B> () {
return (custom: Observable<T>): Observable<U> =>
custom.pipe(map((x: T) => x.value ));
}
有趣的是,至少在我的情況下,如果我沒有myObs$在這一行中宣告like的型別
myObs$ = mySub.pipe(customOperator_())
推斷的型別myObs$是Observable<A | B>但是,同時,如果我嘗試這樣的事情
myObs$: : Observable<B> = mySub.pipe(customOperator_())
我從編譯器中得到一個錯誤Type 'Observable<IModel>' is notassignable to type 'Observable<IModel>',這是正確的,因為mySub通知型別的物件IModel<A>。
同時,如果我嘗試這樣的事情
myObs$: : Observable<A> = mySub_A.pipe(customOperator_())
編譯器沒有引發錯誤,這又是正確的。
所以@akotech 提出的解決方案比我提出的方案更安全。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/398050.html
上一篇:Python:硒查找元素角度
