私は基本的なユニオンタイプを持っています。TypeScriptのユニオンタイプのリストからユニオンタイプを見つけて曖昧さを取り除く方法は?
type A = {type: "A"}
type B = {type: "B"}
type X = A | B
と私は同じ型を持つリスト内の項目を見つける機能があります。
function find(x: X, list: Array<X>) {
return list.find(item => item.type === x.type)
}
私は、この関数の戻り値の型が一致したXの特定のサブタイプであることを期待します入力x。つまり、find({type: "A"}, [{type: "A"}, {type: "B"}])
はAのタイプを返すようにします。
どうすればいいですか?
編集:私が扱っていることはもう少し複雑です。私は、キューされているバッチの概念を持っていると私はそれが存在する場合、バッチにアイテムを追加したい、そう私は新しいバッチをエンキューしたい:
type A = { type: "A" }
type B = { type: "B" }
type X = A | B
type Batch<T extends X> = { type: T["type"]; batch: Array<T> }
type BatchA = Batch<A>
type BatchB = Batch<B>
type BatchTypes = BatchA | BatchB
function find(x: X, list: Array<BatchTypes>) {
return list.find(item => item.type === x.type)
}
function enqueue(x: X, queue: Array<BatchTypes>) {
const result = find(x, queue)
if (result) {
result.batch.push(x)
} else {
queue.push({type: x.type, batch:[x]})
}
}
let a: A
let b: B
let queue: Array<BatchTypes>
enqueue(a, queue)
enqueue(b, queue)
の労働組合を引き起こすので、ここでの問題はenqueue
にあります両方のタイプ。私は種類をオーバーロードしようとすると、結果が適切に解決が、問題はfind
の最初の引数でありますし、キューに新しいバッチを推進している。
function find(x: A, list: Array<BatchTypes>): BatchA
function find(x: B, list: Array<BatchTypes>): BatchB
function find(x: X, list: Array<BatchTypes>) {
return list.find(item => item.type === x.type)
}
function enqueue(x: A, queue: Array<BatchTypes>)
function enqueue(x: B, queue: Array<BatchTypes>)
function enqueue(x: X, queue: Array<BatchTypes>) {
const result = find(x, queue)
if (result) {
result.batch.push(x)
} else {
queue.push({ type: x.type, batch: [x] })
}
}
これを明確にする良い方法があります場合は私に知らせてください質問。 @のアルテムの答えを考える
、私は近い得ている:
function find<T extends X>(x: T, list: Array<BatchTypes>): Batch<T> {
return <Batch<T>>list.find(item => item.type === x.type)
}
function enqueue<T extends X>(x: T, queue: Array<BatchTypes>) {
const result = find(x, queue)
if (result) {
result.batch.push(x)
} else {
queue.push({ type: x.type, batch: [x] })
}
}
をしかし、問題はqueue.push
にまだあります。
多分これは、現在の問題を実証するより簡潔な例です。
type A = { type: "A" }
type B = { type: "B" }
type X = A | B
let list: Array<Array<A> | Array<B>>
function append<T extends X>(x: T) {
list.push([x])
}
function append2(x: X) {
list.push([x])
}
興味深い。そのオーバーロードを行うために、Xのすべてのユニオンタイプを反復処理する方法はありますか? – Chet
私は反復する方法はないと思っていますが、 'find'の戻り値の型と最初の引数の型が同じであることを表すために、単一の汎用宣言を使用することができます。私は答えを更新しました。 – artem
私が追加した編集をチェックアウト - これはそこにある方法の一部です... – Chet