【发布时间】:2018-01-12 20:46:45
【问题描述】:
我有一个基本的联合类型;
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] })
}
}
如果有更好的方法来澄清这个问题,请告诉我。
鉴于@artem 的回答,我已经接近了:
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])
}
【问题讨论】:
标签: typescript