シンプルストリーム(FRP)を実装するTypescriptでクラスを作成しました。今私はクライアント側の機能(イベントのストリーム)でそれを拡張したいと思います。私の問題を説明するために、ここにいくつかの疑似コードがあります:Typescriptでこのオブジェクトデザインを改善するにはどうすればよいですか?
class Stream<T> {
map<U>(f: (value: T) => U): Stream<U> {
// Creates a new Stream instance that maps the values.
}
// Quite a few other functions that return new instances.
}
このクラスは、サーバーとクライアントの両方で使用できます。クライアント側では、私はこの1つを拡張するクラスを作成しました:
class ClientStream<T> extends Stream<T> {
watch(events: string, selector: string): Stream<Event> {
// Creates a new ClientStream instance
}
}
今ClientStream
クラス約map
を知っているがStream
クラス約watch
を知りません。これを回避するために、関数はファクトリメソッドを呼び出します。
protected create<U>(.....): Stream<U> {
return new Stream<U>(.....)
}
ClientStream
クラスはClientStream
インスタンスを返すために、この機能を無効にします。ただし、コンパイラは、ClientStream.map
がClientStream
ではなく、Stream
を返すと不平を言います。それは、キャストを使用して '解決'することができますが、醜いことに加えて連鎖を防止します。この問題を呈する
例コード:
class Stream {
protected create(): Stream {
return new Stream()
}
map() {
return this.create()
}
}
class ClientStream extends Stream {
protected create(): ClientStream {
return new ClientStream()
}
watch() {
return this.create()
}
}
let s = new ClientStream().map().watch()
コンパイラによると、ストリームはmap
から返されるので、これはコンパイルされませんがClientStream
ではありません。error TS2339: Property 'watch' does not exist on type 'Stream'.
私は本当にこのようにしないでくださいパターンはありますが、私はよりエレガントなソリューションはありません。私が考えたこと:
- 使用組成(デコレータ)。私がプロキシを通過させなければならないメソッドの数を考えると、実際にはオプションではありません。
ClientStream
について心配することなく、後でStream
にメソッドを追加できるようにしたいと思います。 Stream
をClientStream
にミックスします。多かれ少なかれ同じ問題があり、ClientStream
は混在しようとしている関数のシグネチャを知っていなければなりませんか?教えてください。- これらのクラスを1つに統合します。これは最後の手段であり、
watch
の機能はサーバー上に存在しません。
優れた(よりエレガントな)ソリューションがありますか?より機能的なスタイルに近づくアイデアがあるなら、それについて聞いて嬉しいです。ありがとう!
ファクトリメソッドは静的にできますか?あるいは、インスタンスデータに依存していますか? –
はい、静的である可能性があります。 –
@SebastianSebaldが述べたように、 '多型この型'を使うことができますが、あなたのクラスは一般的なので難しくなります。私はまだあなたの問題を理解しようとしています。おそらく、問題を示す完全な例でコードを更新できますか?私はちょうど遊び場に貼り付けることができ、エラーが何で、どこにあるか見ることができます。 –