简体   繁体   English

以类型安全的方式检查对象中的可能属性

[英]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.

相关问题 TypeScript:是否可以安全地访问给定键数组的 object 的嵌套属性? 这可以以类型安全且可组合的方式完成吗? - TypeScript: Is it possible to safely access nested properties of an object given an array of keys? Can this be done in a type safe and composable way? 如何以类型安全的方式迭代记录类型 object 的枚举属性? - how to iterate on enum properties of a record type object in a type-safe way? 以类型安全的方式迭代 object 属性 - Iterate object properties in a type-safe manner Typescript 未能检查 function 类型和 object 类型的联合中的属性 - Typescript fail checking for properties in the union of a function type and a object type 是否有一种类型安全的方法可以将较大的 object 减少()为 typescript 中的新类型? - Is there a type-safe way to reduce() a larger object into a new type in typescript? 使用Object.defineProperty动态创建的类型检查属性 - Type-checking properties created dynamically with Object.defineProperty 使用类型安全的方法在对象中保存多种类型 - Type safe way to hold multiple types within object 可以禁用类型检查吗? - Possible to disable type checking? 有没有一种方法可以键入对象,以便扩展接口的所有属性都是给定类型? - Is there a way to type an object so that all properties of extended interface are a given type? 类型联合不检查多余的属性 - Type union not checking for excess properties
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM