簡體   English   中英

以類型安全的方式檢查對象中的可能屬性

[英]Checking for possible properties in an object in a type safe way

TypeScript 2.0支持如下標記的聯合:

type Foo = {
  tag: 'foo'
  x: number
}

type Bar = {
  tag: 'bar'
  y: string
}

type FooOrBar = Foo | Bar

然后我們可以使用類型安全的方式來區分這兩種情況:

function doStuff(foobar: FooOrBar) {
  if (foobar.tag === 'foo') {
    console.log(foobar.x + 3)
  } else {
    console.log(foobar.y.length)
  }
}

一切都很好。 但是實際上,區分這些類型並不是嚴格必需的tag字段。 我們可以設想這樣做:

type Foo2 = {
  x: number
}

type Bar2 = {
  y: string
}

type Foo2OrBar2 = Foo2 | Bar2

有沒有類似的方法可以以類型安全的方式對此類聯合進行案例分析? 顯而易見的事情不起作用:

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)
  }
}

還有另一種方法嗎?

我想出了如何使用泛型類型衛士來做到這一點:

function hasKey<K extends string>(k: K, o: any): o is { [_ in K]: any } {
  return typeof o === 'object' && k in o
}

然后工作:

function doStuff2(foobar: Foo2OrBar2) {
  if (hasKey('x', foobar)) {
    console.log(foobar.x + 5)
  } else {
    console.log(foobar.y.length)
  }
}

更新

有用於制作打字稿票in執行作為一種組織后衛:

https://github.com/Microsoft/TypeScript/issues/10485

您可以嘗試如下操作:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM