[英]Checking for possible properties in an object in a type safe way
TypeScript 2.0 supports tagged unions like this: TypeScript 2.0支持如下标记的联合:
type Foo = {
tag: 'foo'
x: number
}
type Bar = {
tag: 'bar'
y: string
}
type FooOrBar = Foo | Bar
and then we can discriminate between the cases in a typesafe way: 然后我们可以使用类型安全的方式来区分这两种情况:
function doStuff(foobar: FooOrBar) {
if (foobar.tag === 'foo') {
console.log(foobar.x + 3)
} else {
console.log(foobar.y.length)
}
}
All well and good. 一切都很好。 But really the
tag
field isn't strictly necessary in order to distinguish these types. 但是实际上,区分这些类型并不是严格必需的
tag
字段。 We could conceive of doing this: 我们可以设想这样做:
type Foo2 = {
x: number
}
type Bar2 = {
y: string
}
type Foo2OrBar2 = Foo2 | Bar2
Is there a similar way I can do case analysis on such a union in a typesafe way? 有没有类似的方法可以以类型安全的方式对此类联合进行案例分析? The obvious thing doesn't work:
显而易见的事情不起作用:
function doStuff2(foobar: Foo2OrBar2) {
if ('x' in foobar) {
// Type error: Property 'x' does not exist on type 'Bar2'
console.log(foobar.x + 5)
} else {
// Type error: Property 'y' does not exist on type 'Foo2'
console.log(foobar.y.length)
}
}
Is there another way to do it? 还有另一种方法吗?
I figured out how to do this with a generic type guard : 我想出了如何使用泛型类型卫士来做到这一点:
function hasKey<K extends string>(k: K, o: any): o is { [_ in K]: any } {
return typeof o === 'object' && k in o
}
Then this works: 然后工作:
function doStuff2(foobar: Foo2OrBar2) {
if (hasKey('x', foobar)) {
console.log(foobar.x + 5)
} else {
console.log(foobar.y.length)
}
}
UPDATE 更新
There's a TypeScript ticket for making in
perform as a type guard: 有用于制作打字稿票
in
执行作为一种组织后卫:
https://github.com/Microsoft/TypeScript/issues/10485 https://github.com/Microsoft/TypeScript/issues/10485
You can try something like this: 您可以尝试如下操作:
function doStuff2(foobar: Foo2OrBar2) {
if ((<Foo2>foobar).x != undefined){
console.log((<Foo2>foobar).x + 5)
} else {
console.log((<Bar2>foobar).y.length)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.