我有一个非常大的联合类型,其成员具有多种类型且有一些重叠。实际上,这些都是真正大型数据库模式中的各种类型的记录属性。
type A = { x: number; y: number }
type B = { y: number; z: number }
// many many more types
type All =
| A
| B
// many many more types
我有一个非常通用的函数,它接受任何类型并根据某些属性的存在做某事。问题是我无法检查是否存在属性,因为Typescript会抛出并且错误地说这个联合中的某些类型没有该属性。但理想情况下,我可以检查是否存在,而Typescript将根据该属性的存在推断出类型......
function f(value: All) {
if (value.x) {
// value must be A or anything that has an x property
} else if (value.y) {
// value must be B or anything that has an x property
}
}
任何想法如何使这项工作?
答案 0 :(得分:3)
是的,你可以这样做:
type A = { x: number; y: number }
type B = { y: number; z: number }
type C = { z: number; x: number }
type D = { y: number; w: number }
type E = { w: number; z: number }
type All = A | B | C | D | E ;
function hasKey<K extends string>(key: K, val: any): val is {[P in K]: any} {
return key in val;
}
function f(v: All) {
if (hasKey('x', v)) {
v // A | C
} else if (hasKey('y',v)) {
v // B | D
} else {
v // E
}
}
hasKey
函数是一个用户定义的类型保护,它将为您缩小工会范围。
答案 1 :(得分:0)
基于jcalz Answer,我更喜欢一种不需要专用库函数的方法:
type A = { x: number; y: number }
type B = { y: number; z: number }
type C = { z: number; x: number }
type D = { y: number; w: number }
type E = { w: number; z: number }
type All = A | B | C | D | E ;
function f(v: All) {
if ('x' in v)) {
v // A | C
} else if ('y' in v)) {
v // B | D
} else {
v // E
}
}
我认为通过阅读可以更好地理解这种方法。