1
我有一個基本的聯合類型;如何從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