簡體   English   中英

如何處理`Type | typescript 和錯誤檢查/測試中的布爾值返回值

[英]how to handle `Type | boolean` return values in typescript and error checking / tests

我有一個 function 可以返回找到的 object,或者失敗。 在失敗情況下返回的最佳值是多少? {}|null|undefined|false

問題是我的測試依賴於這個 object,但我收到 typescript 警告,因為也可以返回false

    const actualResult: ActionResult | boolean = await findAndRunAction(evt)
    if (actualResult) {
      expect(actualResult.klass).toBe('room')

在哪里

function findAndRunAction(): ActionResult | false { 
// if found
return obj: ActionResult
// else
return false
 }

typescript 足夠聰明,知道該值必須是truthy的,但這應該是當我返回完整 object 的實例時,而不僅僅是true

我可能會拋出錯誤,或者另一種方法是始終返回相同的 object 類型,但只需在 object 中添加一個ok: true|false字段。 這似乎有點過分,但我想這確實意味着我總是只有一種返回類型......

請推薦在 TS 中使用的好模式!

ts問題

未通過測試

編譯器失敗,但實際測試通過了。

更新:我做了這樣的事情:

// define all the other fields as optional

interface ActionResult {
  ok: boolean
  doc?: ActionData
  events?: string[]
  klass?: string
}

// so I can just return an empty obj in fail case

    return {
      ok: false
    }

我不太喜歡這個,因為它在所有這些選項中減少了實際類型的剛性。

有幾種方法可以 go 關於這一點,因為您使用的是帶有原語的聯合類型,最簡單的解決方案是對 boolean 進行typeof檢查,例如

  if (typeof actualResult !== 'boolean') {

編譯器足夠聰明,可以將選項縮小到單個ActionResult 這適用於原語,但僅提供淺層檢查,因此無法正確區分對象。

此外,如果您有兩個以上的返回類型,這將非常笨拙,因為您必須排除每個人(並且鏈接else if不會不斷縮小剩下的類型,您必須將它們嵌套在其中,這將變得令人困惑else if地獄景觀),所以一個(仍然不完美)選項是使用 generics 和屬性檢查來實現您自己的 typeof 檢查。

我從how-to-use-typescript-type-guards得到了這個片段,它已經好幾次了:

export const isOfType = <T>(
  varToBeChecked: any,
  propertyToCheckFor: keyof T,
): varToBeChecked is T =>
  (varToBeChecked as T)[propertyToCheckFor] !== undefined;

這個小實用程序 function 將允許您將測試調整為:

test('should test', () => {
  const actualResult = findAndRunAction(false);
  if (isOfType<ActionResult>(actualResult, 'klass')) {
    expect(actualResult.klass).toBe('room');
  }
});

這將編譯,但它並不完美。 我們假設klass是 function 的返回類型之間的唯一屬性,它需要深入了解您正在檢查的類型的屬性,因此它不是一個非常抽象的解決方案,但在返回的一些簡單情況下可能會有所幫助是兩個不同結構的對象。

在像這樣簡單的情況下,我可能只選擇第一個選項,但根據您的需要決定:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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